Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/252.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
CakePHP模型保存到错误的表_Php_Cakephp - Fatal编程技术网

CakePHP模型保存到错误的表

CakePHP模型保存到错误的表,php,cakephp,Php,Cakephp,在我的用户模型中,我有以下关系: public $hasAndBelongsToMany = array( 'User'=>array( 'className' => 'User', 'joinTable' => 'friends', 'with' => 'Friend',

在我的用户模型中,我有以下关系:

public $hasAndBelongsToMany = array(
        'User'=>array(
            'className'              => 'User',
            'joinTable'              => 'friends',
            'with'                   => 'Friend',
            'foreignKey'             => 'user_id',
            'associationForeignKey'  => 'friend_id'
        )
);
它将用户链接到作为朋友的用户。但是,当我对单个用户执行某些操作时,例如更改密码或编辑用户详细信息(与好友无关),它将开始在好友表中执行某些操作,例如删除所有现有记录,然后添加空行数据

我把关系安排错了吗?命名是否应该不同,这样当我处理
$this->User
时,它就不会触动朋友了


编辑:自发布此问题以来,我已将用户id和朋友id更改为user1\u id和user2\u id,以防止通过假设字段是主键或nIcO解释的任何内容对字段进行任何自动标记。但同样的问题仍然存在

您的联接表名为
friends
,并使用名为
friends
的模型。通过查看HABTM关系声明,似乎
friends
表包含一个名为
user\u id
的字段和一个名为
friends\u id
的字段

friends
表中有一个
friends\u id
字段就像在
users
表中有一个
user\u id
字段一样,您可能不会这样做。我猜Cake不喜欢它,因为Cake认为
friend\u id
是指向另一个名为
friend
的模型的外键


无论如何,使用HABTM关系处理同一个表之间的HABTM并不容易(请参见),您可能应该使用连接模型(请参见)

我强烈建议使用真正的Friends模型来处理。设置如下:

User hasMany FriendList
User hasMany FriendOf (alias of FriendList)

FriendList belongsTo User
FriendList belongsTo Friend (alias of User)
示例代码:

Table definitions (skeleton):

users:
  id
  name

friend_lists:
  id
  user_id
  friend_id

Model Definitions:

class User extends AppModel {
  var $hasMany = array(
    'FriendList',
    'FriendOf' => array(
      'className' => 'FriendList',
      'foreignKey' => 'friend_id'
    )
  );
}

class FriendList extends AppModel {
  var $belongsTo = array(
    'User',
    'Friend' => array(
      'className' => 'User',
      'foreignKey' => 'friend_id'
     )
  );
}

不要创建与HasandBelongToMany关系中使用的别名/名称相同的模型。这只会让我头疼CakePHP

比如,

我有一个名为“公司”的模型,它有HABTM“用户”记录。因此,在我的数据库中有一个名为“companyies_users”的表

在你的公司模式中,你可能会受到这样的诱惑

var $hasAndBelongsToMany = array(
    'User'=>array('with'=>'CompanyUser')
);
然后创建一个“CompanyUser”模型,因为您希望在关联中存储额外的数据

不要这样做。我不知道为什么,但Cake无法预测何时会自动创建名为“CompanyUser”的模型,何时会实际加载您创建的PHP文件

在您的模型中,最好定义HABTM使用默认关联,然后从表中创建一个不同名称的模型,并使用该模型处理记录。这确保了CakePHP也将使用自动生成的模型并正常工作

因此,在我的示例中,我创建了一个名为“Members”的模型,该模型将“useTable”变量设置为“companys\u users”

现在我知道当我使用“Company”模型时,CakePHP将正确处理HABTM,如果我需要访问这些连接记录,那么我使用“Members”模型

使用“with”选项的风险在于,您永远不知道CakePHP何时会失败,并自动生成模式。在这种情况下,您的任何回调或行为都不会发生

编辑:

更直接地回答问题

修改User.php模型文件,以便HABTM使用更多的默认值

 public $hasAndBelongsToMany = array('Friend');

确保没有为联接表定义UserFriend.php模型文件。如果需要修改联接表,请在数据库中使用具有指向该表的不同别名的模型。

我猜您的问题是由于不正确地声明关联造成的。试试这个:

public $hasAndBelongsToMany = array(
        'Friend'=>array(
            'className'              => 'Friend',
            'joinTable'              => 'friends',
            'foreignKey'             => 'user_id',
            'associationForeignKey'  => 'friend_id'
        )
);

建立友谊协会有几种方法,因为友谊有两个方向。可以说用户A是用户B的朋友,但用户B也是用户A的朋友

当一个人在数据库中建立友谊时。您必须在联接表中创建两条记录,以在两个方向上表示这种友谊(假设您想要双向)

这涵盖了方向的概念

您可能会遇到记录消失的问题,因为默认情况下,CakePHP会在更新记录时删除记录的所有连接数据行。请查看HABTM上“唯一”选项的说明

unique:如果为true(默认值),则在更新记录时,cake将首先删除外键表中的现有关系记录,然后再插入新记录。因此,更新时需要再次传递现有关联

这意味着您在更新记录时必须始终包含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\u users”是HABTM join表。注意名称,它是users\u users,因为它正在加入自身

您仍然需要在CakePHP中创建两个模型

第一个是User.php,它将描述系统中的用户。我们将主要使用CakePHP中的默认值来实现这一点。所以HABTM只是一句“朋友”

class User extends AppModel
{
    var $name = 'User';
    var $hasAndBelongsToMany = array(
          'Friend'
    );
}
现在,CakePHP会抱怨缺少表用户朋友。我们需要创建一个Friend模型,但将其指向users表

class Friend extends AppModel
{
    var $name = 'Friend';
    var $useTable = 'users';
}
现在CakePHP将使用users\u users表作为连接。朋友模型现在描述的是作为朋友的用户

重要的是要明白,你必须在两个方向上建立朋友。当您为用户A保存数据并说他/她是用户B的朋友时,您还必须保存用户B并说他/她是用户A的朋友。否则,将只定义一个用户的友谊

这里还有另一个答案,它使用别名定义了友谊的双向性,但我建议不要实现它,因为它为CakePHP添加了应用程序可能不需要的额外SQL查询工作。读取用户A的记录时,
public $hasAndBelongsToMany = array(
        'User' => array(
                ....
                'unique' => 'keepExisting',
                ....
        ),
);