2

私の CakePHP アプリケーションには、他のユーザーと友達になれるユーザーがいます。

これは、usersテーブルとfriends_users次の列を持つテーブルで行われます:id, user_id, friend_id, statusリレーションシップ。

したがって、ユーザー ID 1 がユーザー ID 2 の友達である場合、user_id 列に 1 があり、friend_id 列に 2 があります。

User のモデルは次のようになります。

public $hasAndBelongsToMany = array(
        'Friend'=>array(
            'className'              => 'User',
            'joinTable'              => 'friends_users',
            'foreignKey'             => 'user_id',
            'associationForeignKey'  => 'friend_id'
        )
    );

ユーザー 1 を表示すると、正常に動作し、ユーザー 2 が友達として表示されます。しかし、ユーザー 2 を表示すると、ユーザー 1 が友達として表示されません。逆に表示すると、データがいっぱいになりません。

ユーザーの友達をリストするために使用する方法は次のとおりです。

$user = $this->User->find('first', array( 
                    'conditions' => array('User.id' => $this->Auth->user('id')),
                    'contain'=>'Profile'
                ));

        $friends = $this->User->find('first', 
            array(
                'conditions'=>array(
                   'User.id'=>$user['User']['id']
                ),
                'contain'=>array(
                    'Profile',
                    'Friend'=>array(
                        'Profile',
                        'conditions'=>array(
                            'FriendsUser.status'=>1
                        )
                    )
                )
            )
        );

        $this->set('friends', $friends);

なぜこれが起こっているのですか?私はドキュメントに目を通しましたが、すべて問題ないようです。

理想的には、他のリソースを指摘されるのではなく、自分のコードを修正したいのです!

ページのクエリ: http://pastebin.com/zQnBVM2X

4

2 に答える 2

2

ユーザー #6 のフレンドを取得すると、フレンド #8 が取得されます。friends_usersユーザー #8 の友達を取得すると、テーブルにユーザー #8 のレコードがないため、何も受信しないはずです。friends_usersそのため、追加のデータをテーブル ( )に挿入するか、 (テーブルを使用せずに) モデルuser_id = 8, friend_id = 6を作成してFriendを介してユーザーを取得する必要がありますFriend。それは頭の体操です。ユーザーは友達であり、友達はユーザーであることを認識する必要があります。

        $friends = $this->User->Friend->find('first', 
            array(
                'conditions'=>array(
                   'Friend.id'=>$id // user id whose friends you need to find
                ),
                'contain'=>array(
                    'Profile',
                    'User'=>array( // here you will get friends
                        'Profile',
                        'conditions'=>array(
                            'FriendsUser.status'=>1
                        )
                    )
                )
            )
        );
于 2012-09-26T23:16:47.727 に答える
0

これは興味深い問題です。数年前に出会い系サイトを構築していたときに、同じ問題に直面しました。

あなたがする必要があるのは、(私の場合)4セットの関係を持つことです:

  • 前方関係
  • 前向きな関係(承認されていない友情)
  • 後方関係
  • 後ろ向きな関係(承認されていない友情)

これにより、必要なすべてのデータを確実に取得し、containable可能な限り使用します。

var $hasAndBelongsToMany = array(
    'ForwardRelation' => array(
        'className'  => 'User',
        'joinTable'  => 'friends_users',
        'foreignKey' => 'user_id',
        'conditions' => array('approved' => '1'),
        'associationForeignKey' => 'friend_id',
        ),
    'ForwardRelationUn' => array(
       'className'  => 'User',
        'joinTable'  => 'friends_users',
        'foreignKey' => 'user_id',
        'conditions' => array('approved' => '0'),
        'associationForeignKey' => 'friend_id'
        ),
    'BackRelation' => array(
        'className'  => 'User',
        'joinTable'  => 'friends_users',
        'foreignKey' => 'friend_id',
        'associationForeignKey' => 'user_id',
        'conditions' => array('approved' => 1)
        ),
    'BackRelationUn' => array(
        'className'  => 'User',
        'joinTable'  => 'friends_users',
        'foreignKey' => 'friend_id',
        'associationForeignKey' => 'user_id',
        'conditions' => array('approved' => '0')
    )
);

いくつかの魔法で動作を追加するafterFind()と、黄金になります!

これは友達を見つけるための私の機能です:

function getFriends( $userid, $search = null ) {

    $Friends    = ClassRegistry::init( 'FriendsUser' );

    $Friends->bindModel( 
        array(
            'belongsTo' => array(
                'User' => array(
                    'className' => 'User',
                    'foreignKey' => 'user_id'
                ),
                'Friend' => array(
                    'className' => 'User',
                    'foreignKey' => 'friend_id'
                    )
                )
            )
        );

    $data = $Friends->find( 
        'all', 
        array( 
            'fields' => array( 
                'DISTINCT FriendsUser.friend_id', 
                'FriendsUser.user_id',
                'FriendsUser.approved',
                'User.id', 
                'User.username', 
                'Friend.id', 
                'Friend.username'
                ), 
            'conditions' => array(
                 'AND' => array(
                     'OR' => array( 
                        'Friend.username LIKE' => '%' . $search . '%',
                        'User.username LIKE' => '%' . $search . '%'
                        )
                    )
                ),
            'contain' => array(
                'User', 
                'Friend'
                ),
            'order' => array( 'User.username ASC', 'FriendsUser.approved DESC' )
        ) 
    );


    $friendlist = array();
    $i = 0;

    foreach ( $data as $datum ) {

        foreach ( $datum as $key => $value ) {

            if ( in_array( $key, array( 'User', 'Friend' ) ) ) {

                if ( $value['id'] == $userid ) {
                    $friendlist[$i]['Me'] = $value;
                } else {
                    $friendlist[$i]['Friend']           = $value;
                }

            }
        }

        $i++;

    }

    $matches = array();

    foreach ( $friendlist as $friend ) {

        if ( stripos( $friend['Friend']['username'], $search ) !== false )
            $matches[ $friend['Friend']['id'] ] = $friend['Friend']['username'];

    }

    asort( $matches );

    $i = 0;

    $newmatches = array();

    foreach ( $matches as $key => $match ) {
        $newmatches[$i]['Tag']['caption']   = $match;
        $newmatches[$i]['Tag']['value']     = $key; 
        $newmatches[$i]['Tag']['image']     = $this->getProfileImage( $key );

        $i++;       
    }

    return $newmatches;

}
于 2012-09-26T23:07:21.660 に答える