我在使用CakePHP 2建立友谊时遇到了麻烦。
我有两个数据库表:用户和朋友。我的用户表包含以下列:
我的朋友表包含以下列:
我的朋友在我的用户模型中设置为hasAndBelongsToMany关系:
<?php
class User extends AppModel {
public $hasAndBelongsToMany = array(
'Friends' => array(
'className' => 'User',
'joinTable' => 'friends',
'foreignKey' => 'user_id',
'associationForeignKey' => 'friend_id',
'unique' => true
)
);
}
现在,当我尝试为用户检索朋友时,它只列出指定用户发起的友谊,即user_id
等于用户ID;它没有向我显示其他人可能已发起请求的朋友(即当前用户的ID在friend_id
列中的位置)。
如何获取朋友,以便user_id
或friend_id
列等于特定ID的记录?
答案 0 :(得分:2)
我认为您不了解HABTM的工作原理。阅读this part of the book。除了用于关系工作的表之外,还需要一个friends_users表。我想如果你打算以这种方式进行设置,你需要将友谊定义为拥有并属于许多用户。
但是,我怀疑你当前的设置是否需要HABTM关系。它似乎是一个用户 hasMany 的朋友,就是这样。考虑使用这种关系,它会按照您的预期为您提供相关的ID。不要忘记定义朋友 belongsTo 用户。
这里有我的规范Cake 2.0友谊教程。我下载了cakePHP 2.1,所以我有一个新的开始。我首先更改了安全盐和密码,然后添加了我的数据库连接。然后我按如下方式构建了我的数据库:
<强>数据库强>:
users
表:
id | int(11)
created | datetime
username | varchar(255)
friendships
表:
id | int(11)
user_from | varchar(255)
user_to | varchar(255)
created | datetime
status | varchar(50)
显然,你的用户表可以/将会有更多东西,但这是我需要的最小值。
<强>模型强>:
好的,这是棘手的部分。以下是我在用户模型中定义的关系。
class User extends AppModel {
/* Other code if you have it */
var $hasMany = array(
'FriendFrom'=>array(
'className'=>'Friendship',
'foreignKey'=>'user_from'
),
'FriendTo'=>array(
'className'=>'Friendship',
'foreignKey'=>'user_to'
)
);
var $hasAndBelongsToMany = array(
'UserFriendship' => array(
'className' => 'User',
'joinTable' => 'friendships',
'foreignKey' => 'user_from',
'associationForeignKey' => 'user_to'
)
);
/* Again, other code */
}
这是我的友谊模型:
class Friendship extends AppModel {
/* Other code if you have it */
var $belongsTo = array(
'UserFrom'=>array(
'className'=>'User',
'foreignKey'=>'user_from'
),
'UserTo'=>array(
'className'=>'User',
'foreignKey'=>'user_to'
)
);
/* Again, other code */
}
关于模型的注意事项:友谊模型属于2个用户。用户模型有3个关联。用户模型中的两个有很多关系都是访问友谊模型数据的别名,因此我们可以使用来自控制器的$this->User->FriendTo
或$this->User->FriendFrom
来获取友谊模型。我首先调用了这些UserFrom和UserTo,反映了友谊模型的设置,但是Cake提出了一个关于相似性的问题,所以我不得不让它们更加清晰。
控制器和视图:
我使用烘焙实用程序烘焙了控制器和视图。然后,我创建了两个用户(丹尼尔和马丁),并创建了从丹尼尔到马丁的新友谊,状态为requested
。然后我将友谊状态更新为confirmed
。
我创建了以下无视自定义用户操作,以演示来自UsersController的友情数据检索:
public function test() {
$data = $this->User->FriendFrom->find('all',
array(
'conditions'=>array('user_from'=>1),
'contain'=>array('UserTo')
)
);
die(debug($data));
}
此查找使用UserModel的hasMany关系来访问Friendship模型,并获取id为1的用户启动关系的关系的相关user_from
和user_to
数据。
您的具体发现:
马丁,你正在寻找的发现在这个系统下是非常简单的,虽然你可以用不同的方式做,但你总是在处理类似的方法,只要有关系总是有两面。你所要做的就是得到一个关系列表,其中你的用户ID是user1或user2(在我的情况下,我知道是谁发起了这种关系,我把它们存储为user_to和user_from-我认为这就是吓到你了)。然后我遍历整个数组,根据我在给定数组中是user1还是2来选择相关的朋友数据。这是一个非常简单的方法,我只是把它放在我的用户模型中。改变骰子(debug());到return $friendslist
能够从你的控制器调用它并获得一个数组。
public function getFriends($idToFind) {
$data = $this->FriendFrom->find('all',
array(
'conditions'=>array(
'OR'=> array(
array('user_to'=> $idToFind),
array('user_from'=> $idToFind)
)
)
)
);
$friendslist = array();
foreach ($data as $i) {
if ($i['FriendFrom']['user_from'] == $idToFind){
$friendslist[] = $i['UserTo'];
}
elseif ($i['FriendFrom']['user_to'] == $idToFind){
$friendslist[] = $i['UserFrom'];
}
}
die(debug($friendslist));
}