CakePHP 2.x中的友谊

时间:2012-06-30 21:53:11

标签: cakephp cakephp-2.0

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

我有两个数据库表:用户朋友。我的用户表包含以下列:

  • ID
  • 电子邮件
  • 密码

我的朋友表包含以下列:

  • ID
  • USER_ID
  • friend_id
  • 批准

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

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

现在,当我尝试为用户检索朋友时,它只列出指定用户发起的友谊,即user_id等于用户ID;它没有向我显示其他人可能已发起请求的朋友(即当前用户的ID在friend_id列中的位置)。

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

1 个答案:

答案 0 :(得分:2)

我认为您不了解HABTM的工作原理。阅读this part of the book。除了用于关系工作的表之外,还需要一个friends_users表。我想如果你打算以这种方式进行设置,你需要将友谊定义为拥有并属于许多用户。

但是,我怀疑你当前的设置是否需要HABTM关系。它似乎是一个用户 hasMany 的朋友,就是这样。考虑使用这种关系,它会按照您的预期为您提供相关的ID。不要忘记定义朋友 belongsTo 用户。


这里有我的规范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个关联。用户模型中的两个有很多关系都是访问友谊模型数据的别名,因此我们可以使用来自控制器的$this->User->FriendTo$this->User->FriendFrom来获取友谊模型。我首先调用了这些UserFrom和UserTo,反映了友谊模型的设置,但是Cake提出了一个关于相似性的问题,所以我不得不让它们更加清晰。

控制器和视图: 我使用烘焙实用程序烘焙了控制器和视图。然后,我创建了两个用户(丹尼尔和马丁),并创建了从丹尼尔到马丁的新友谊,状态为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来选择相关的朋友数据。这是一个非常简单的方法,我只是把它放在我的用户模型中。改变骰子(debug());到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));
}