0

我在使用 CakePHP 2 建立友谊时遇到了麻烦。

我有两个数据库表:usersfriends。我的用户表有以下列:

  • ID
  • 电子邮件
  • 密码

我的朋友表有以下列:

  • ID
  • 用户身份
  • 朋友ID
  • 得到正式认可的

我在我的用户模型中将朋友设置为 hasAndBelongsToMany 关系:

<?php
class User extends AppModel {
    public $hasAndBelongsToMany = array(
        'Friends' => array(
            'className' => 'User',
            'joinTable' => 'friends',
            'foreignKey' => 'user_id',
            'associationForeignKey' => 'friend_id',
            'unique' => true
        )
    );
}

现在,当我尝试为用户检索好友时,它只列出指定用户发起的好友关系,即 whereuser_id等于用户 ID;它不会向我显示其他人可能发起请求的位置(即当前用户的 ID 在friend_id列中的位置)。

我如何获取朋友,以便记录user_idfriend_id列等于特定 ID 的记录?

4

1 回答 1

2

我认为您不了解 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->FriendToor $this->User->FriendFromfrom 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_fromuser_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));
}
于 2012-06-30T22:25:47.853 回答