我认为您不了解 HABTM 的工作原理。阅读本书的这一部分。除了您拥有的表之外,您还需要一个 friends_users 表才能使关系正常工作。我认为,如果您要以这种方式进行设置,则需要将友谊定义为拥有并属于许多用户。
但是,我质疑您当前的设置是否需要 HABTM 关系。好像一个用户有很多朋友,仅此而已。研究使用这种关系,它会按照您的预期为您提供相关的 ID。不要忘记定义 Friend belongsTo User。
这是我的经典 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 个关联。User Model 中的两个 hasMany 关系都是访问 Friendship 模型数据的别名,所以我们可以使用$this->User->FriendTo
or $this->User->FriendFrom
from controllers 来访问 Friendship 模型。起初我将它们命名为 UserFrom 和 UserTo,反映了 Friendship 模型的设置,但 Cake 对相似之处提出了质疑,因此我不得不让它们更加不同。
控制器和视图:我使用 bake 实用程序烘焙控制器和视图。然后我创建了两个用户(Daniel 和 Martin),并创建了一个从 Daniel 到 Martin 的新友谊,状态为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 来选择相关的朋友数据。这是一个非常简单的方法,我只是把它放在我的用户模型中。改变模具(调试());以便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));
}