在我的用户模型中,我有以下关系:
public $hasAndBelongsToMany = array(
'User'=>array(
'className' => 'User',
'joinTable' => 'friends',
'with' => 'Friend',
'foreignKey' => 'user_id',
'associationForeignKey' => 'friend_id'
)
);
将用户作为朋友链接到用户.但是,当我对单个用户执行某些操作(如更改密码或编辑用户详细信息(与朋友无关))时,它将开始在friends表中执行操作,例如删除所有现有记录,然后添加空行数据. .
我把关系弄错了吗?如果命名不同,那么当我处理$this->用户时,它不会触及朋友吗?
编辑:自发布此问题以来,我已将user_id和friend_id更改为user1_id和user2_id,以防止Cake对字段执行任何自动化,假设它们是主键或nIcO下面解释的任何内容.但同样的问题仍然存在!
最佳答案 实现友谊协会有几种方法,因为友谊中有两个方向.你可以说用户A是用户B的朋友,但用户B是用户A的朋友.
当一个人在数据库中创建友谊时.您必须在连接表中创建两个记录才能在两个方向上表示这种友谊(假设您需要双向).
这涵盖了方向的概念.
您可能遇到记录消失的问题,因为默认情况下CakePHP会在更新时删除记录的所有连接数据行.看一下HABTM上“独特”选项的描述.
unique: If true (default value) cake will first delete existing relationship records in the foreign keys table before inserting new ones, when updating a record. So existing associations need to be passed again when updating.
这意味着您在更新记录时始终必须包含HABTM数据.否则,这些记录将被删除,并通过传递的内容进行更新.
现在,您可以创建的最基本的友谊设置将涉及两个表.
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(45) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `users_users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(10) unsigned NOT NULL,
`friend_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `user` (`user_id`),
KEY `friend` (`friend_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
第一个表’users’将保存我们的用户数据,第二个’users_users’是HABTM连接表.注意名称,它是users_users,因为它正在加入自己.
您仍然需要在CakePHP中创建两个模型.
第一个是User.php,它将描述系统中的用户.我们将主要使用CakePHP中的默认值来实现此功能.所以HABTM只是一行’朋友’.
class User extends AppModel
{
var $name = 'User';
var $hasAndBelongsToMany = array(
'Friend'
);
}
现在,CakePHP会抱怨表users_friends丢失了.我们需要创建一个Friend模型,而是将其指向users表.
class Friend extends AppModel
{
var $name = 'Friend';
var $useTable = 'users';
}
现在CakePHP将使用users_users表作为连接.朋友模型现在描述了作为朋友的用户.
重要的是要了解您必须在两个方向创建朋友.当您为用户A保存数据时,他/她是用户B的朋友,那么您还必须保存用户B并说他/她是用户A的朋友.否则,只有一个用户将定义友谊.
这里有另一个答案,它定义了使用别名的友谊的双重方向,但我建议不实现它,因为它为CakePHP添加了额外的SQL查询工作,您的应用程序可能不需要它.当您阅读用户A的记录时,您只需要知道他们的朋友是谁,但没有相反的方式.
您可以创建一个行为,确保在更新用户记录时,友谊会双向进行.那会更有效率.
NOTE: My code example is for CakePHP 1.3 which is what I’m currently using, but it should work in 2.x just fine.