在CakePHP中使用两列ID列出数据
我在CakePHP中构建了一个简单的friends系统,它有两个表:用户和朋友在CakePHP中使用两列ID列出数据,php,cakephp,Php,Cakephp,我在CakePHP中构建了一个简单的friends系统,它有两个表:用户和朋友 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
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
),
)
);
现在,当它在friends表中提取用户id匹配的朋友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
),
)
);
但是,如果我假设有大量用户,那么性能可能会很差。我想您希望这是一个递归表,以便模型能够正确工作。 基本上,您希望用户成为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'
)
)
);
不过我还是有同样的问题。当我进行查询时,我需要在与模型无关的初始列表中匹配用户id和朋友id。不,这些都不起作用。现在只剩下一个朋友了。也许我可以在我的原始代码中使用数组合并?我完全按照你发布的那样尝试了,但它就是不喜欢。在我的专栏文章中,我根据你的旧答案发布了我尝试过的内容,但与我的代码混合在一起,似乎效果不错。有点脏,但确实管用。虽然我猜它的性能会更差,但您正在查询同一个模型两次。您应该能够将这些条件与或合并到条件数组中。您能举个例子吗?对我来说,它似乎比简单语句更复杂,或者因为我为每个find语句返回不同的字段。ThanksJust返回一个空数组吗?啊,我忘了把语句放在数组中。。。现在试试看,还不行。错误sql是:`SELECT
Friend
id
FROMdb
friends
ASFriend
其中Friend
状态=1和(Friend
Friend\id
=6)或(Friend
用户id
=6))和('Friend.user\id')中的字段`