0

私は2つのテーブルを持つCakePHPで構築されたシンプルな友達システムを持っています:ユーザーと友達

Users
id,
username,
password

Friends
id
user_id
friend_id
status

ユーザーの友達を一覧表示するには、次のようにします。

$user = $this->User->find('first', array( 'conditions' => array('User.username' => $username)));

// First get a list of friend ids
$friendsList = $this->Friend->find('list', 
    array(
        'conditions'=>array(
           'Friend.user_id'=>$user['User']['id'],
           'Friend.status'=>1
        ),
        'fields'=>array(
            'Friend.friend_id'
        )
    )
);

// Then list users with matching ids
$friends = $this->User->find('all', 
    array(
        'conditions'=>array(
           'User.id'=>$friendsList
        ),
    )
);

これで、ユーザーIDがfriendsテーブルで一致するフレンドIDのリストを取得するため、ユーザーがフレンドリングしたフレンドを一覧表示する場合に正常に機能します。問題は、友人がユーザーと友達になった場合、IDが列で逆になり、一方のユーザーを表示したときに友情が表示されないが、もう一方のユーザーは表示されることです...それが理にかなっている場合はどうでしょうか。

これを修正するにはどうすればよいですか?基本的に、ユーザーの両方の列で一致するすべてのIDを見つけてから、その行に一致するフレンドIDまたはユーザーIDを引き出す必要があります。

モデルも投稿しました(ただし、問題は機能している関係ではなくクエリにあるため、この質問では実際には重要ではないと思います)。

ユーザーモデル:

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

フレンドモデルが仮想化されます!

ありがとう

編集:これを行うと問題が修正されます:

// First get a list of friend ids
$friendsList1 = $this->Friend->find('list', 
    array(
        'conditions'=>array(
           'Friend.user_id'=>$user['User']['id'],
           'Friend.status'=>1
        ),
        'fields'=>array(
            'Friend.friend_id'
        )
    )
);

$friendsList2 = $this->Friend->find('list', 
    array(
        'conditions'=>array(
           'Friend.friend_id'=>$user['User']['id'],
           'Friend.status'=>1
        ),
        'fields'=>array(
            'Friend.user_id'
        )
    )
);

$friendsList = array_merge($friendsList1,$friendsList2);

// Then list users with matching ids
$friends = $this->User->find('all', 
    array(
        'conditions'=>array(
           'User.id'=>$friendsList
        ),
    )
);

しかし、私が推測するユーザーのDBが大きい場合、パフォーマンスはかなり低下する可能性があります。

4

1 に答える 1

1

モデルが正しく機能するように、これを再帰テーブルにする必要があると思います。あなたは本質的にユーザーにユーザーをhabtmさせたいです。したがって、モデルは次のようになります。

 public $hasAndBelongsToMany = array(
        'User'=>array(
            'className'              => 'User',
            'joinTable'              => 'users_user',
            'foreignKey'             => 'user_id',
            'associationForeignKey'  => 'friend_id',
            'fields'                 => array('id','user_id','friend_id'),
        )
 );

次に、ユーザーモデルにクエリを実行し、すべての関係を適切に取得できます。そのようです:

$friends = ($this->User->Friend->find('all', array('conditions'=>array(
    'Friend.id'=>$loggedinuserid,
                    "OR" => array (
                     "User.id" => $loggedinuserid,
                    ) 
))));

または、元のモデルが機能する場合:

$friendsList = $this->Friend->find('list', 
    array(
        'conditions'=>array(
           'Friend.status'=>1,
           "OR"=>array(
                 array('Friend.friend_id'=>$user['User']['id']),
                 array('Friend.user_id'=>$user['User']['id'])
                )
        ),
        'fields'=>array(
            'Friend.user_id'
            'Friend.friend_id'
        )
    )
);
于 2012-12-16T10:57:03.783 に答える