就个人而言,我认为 hasAndBelongsToMany 并不适合这种情况。当您想要显示复选框列表或选择列表并允许用户以一种形式选择/管理他们的所有关注者(或任何可能的关系)时,它非常适合。
这可能只是我个人的偏好,但在像您这样的情况下,您添加/删除单个链接而不担心与该用户相关的任何其他链接,我更喜欢只创建一个单独的“关系”(或类似命名) 模型/控制器,并将记录视为本身的事物,而不是只是 hasAndBelongsToMany 链接,这些链接都是“自动”管理的。
这是我的做法:
将您的 users_users 表命名为“relationships”。并将列命名为“followed_by_id”和“following_id”(或类似名称)以避免关于哪个用户是关注者/被关注者的任何歧义(如果这是一个词!)。
在您的用户模型中,您将拥有以下关系:
var $hasMany = array(
'Followers' => array(
'className' => 'Relationship',
'foreignKey' => 'following_id',
'dependent'=> true
),
'FollowingUsers' => array(
'className' => 'Relationship',
'foreignKey' => 'followed_by_id',
'dependent'=> true
),
);
然后你会有一个看起来像这样的关系模型($belongsTo 关系是重要的部分):
<?php
class Relationship extends AppModel {
var $name = 'Relationship';
var $validate = array(
'followed_by_id' => array(
'numeric' => array(
'rule' => array('numeric'),
),
),
'following_id' => array(
'numeric' => array(
'rule' => array('numeric'),
),
),
);
var $belongsTo = array(
'FollowedBy' => array(
'className' => 'User',
'foreignKey' => 'followed_by_id'
),
'Following' => array(
'className' => 'User',
'foreignKey' => 'following_id'
)
);
}
?>
然后在您的关系控制器中,您将拥有如下内容:
function add($following_id = null) {
$this->Relationship->create();
$this->Relationship->set('followed_by_id',$this->Auth->User('id'));
$this->Relationship->set('following_id',$following_id);
if ($this->Relationship->save($this->data)) {
// all good
} else {
// You could throw an error here if you want
$this->Session->setFlash(__('Error. Please, try again.', true));
}
$this->redirect($this->referer());
}
然后要添加关系,您显然只需调用关系控制器的 add 方法。
注意:理想情况下,由于添加关系会更改数据库,因此理想情况下不应通过常规 URL 访问的 GET 请求来完成。应该通过 POST 提交表单来完成。我知道当通过 GET 的常规链接很容易做到这一点时,这似乎有点矫枉过正。在此示例中,我没有费心使用表单/POST - 但如果您想坚持最佳实践,那就是您应该做的。有关更多信息,请参见:https ://softwareengineering.stackexchange.com/questions/188860/why-shouldnt-a-get-request-change-data-on-the-server