在我的CakePHP应用程序中,我的用户可以与其他用户成为朋友。
这是通过users
表和friends_users
表完成的,该表包含以下列:id, user_id, friend_id, status
表示关系。
因此,如果用户ID 1是用户ID为2的朋友,则user_id中的1和friend_id列中的2
用户的模型如下:
public $hasAndBelongsToMany = array(
'Friend'=>array(
'className' => 'User',
'joinTable' => 'friends_users',
'foreignKey' => 'user_id',
'associationForeignKey' => 'friend_id'
)
);
查看用户1时,它工作正常,并将用户2显示为朋友。但是,当查看用户2时,它不会将用户1显示为朋友...因此,当反向查看时,它不会填满数据!
以下是我用来列出用户朋友的方法:
$user = $this->User->find('first', array(
'conditions' => array('User.id' => $this->Auth->user('id')),
'contain'=>'Profile'
));
$friends = $this->User->find('first',
array(
'conditions'=>array(
'User.id'=>$user['User']['id']
),
'contain'=>array(
'Profile',
'Friend'=>array(
'Profile',
'conditions'=>array(
'FriendsUser.status'=>1
)
)
)
)
);
$this->set('friends', $friends);
为什么会发生这种情况?我查看了文档,但对我来说似乎都很好。
理想情况下,我想修复我的代码,而不是指向其他资源!
页面上的查询:http://pastebin.com/zQnBVM2X
答案 0 :(得分:2)
当您为用户#6检索朋友时,您将获得#8朋友。当您为用户#8检索朋友时,您不应该收到任何内容,因为friends_users
表中没有用户#8的记录。因此,您需要在friends_users
表(user_id = 8, friend_id = 6
)中插入其他数据,或者您需要创建Friend
模型(不使用表格)并通过Friend
检索用户。这就是心理体操 - 你需要意识到用户是朋友而朋友是用户。
$friends = $this->User->Friend->find('first',
array(
'conditions'=>array(
'Friend.id'=>$id // user id whose friends you need to find
),
'contain'=>array(
'Profile',
'User'=>array( // here you will get friends
'Profile',
'conditions'=>array(
'FriendsUser.status'=>1
)
)
)
)
);
答案 1 :(得分:0)
这是一个有趣的问题,几年前我在建立约会网站时遇到了同样的问题。
你需要做的是(在我的情况下)4组关系:
这将确保您提取所有必要的数据,尽可能使用containable
。
var $hasAndBelongsToMany = array(
'ForwardRelation' => array(
'className' => 'User',
'joinTable' => 'friends_users',
'foreignKey' => 'user_id',
'conditions' => array('approved' => '1'),
'associationForeignKey' => 'friend_id',
),
'ForwardRelationUn' => array(
'className' => 'User',
'joinTable' => 'friends_users',
'foreignKey' => 'user_id',
'conditions' => array('approved' => '0'),
'associationForeignKey' => 'friend_id'
),
'BackRelation' => array(
'className' => 'User',
'joinTable' => 'friends_users',
'foreignKey' => 'friend_id',
'associationForeignKey' => 'user_id',
'conditions' => array('approved' => 1)
),
'BackRelationUn' => array(
'className' => 'User',
'joinTable' => 'friends_users',
'foreignKey' => 'friend_id',
'associationForeignKey' => 'user_id',
'conditions' => array('approved' => '0')
)
);
添加一些带有afterFind()
魔法的行为,你就会变成金色!
这是我找朋友的功能:
function getFriends( $userid, $search = null ) {
$Friends = ClassRegistry::init( 'FriendsUser' );
$Friends->bindModel(
array(
'belongsTo' => array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id'
),
'Friend' => array(
'className' => 'User',
'foreignKey' => 'friend_id'
)
)
)
);
$data = $Friends->find(
'all',
array(
'fields' => array(
'DISTINCT FriendsUser.friend_id',
'FriendsUser.user_id',
'FriendsUser.approved',
'User.id',
'User.username',
'Friend.id',
'Friend.username'
),
'conditions' => array(
'AND' => array(
'OR' => array(
'Friend.username LIKE' => '%' . $search . '%',
'User.username LIKE' => '%' . $search . '%'
)
)
),
'contain' => array(
'User',
'Friend'
),
'order' => array( 'User.username ASC', 'FriendsUser.approved DESC' )
)
);
$friendlist = array();
$i = 0;
foreach ( $data as $datum ) {
foreach ( $datum as $key => $value ) {
if ( in_array( $key, array( 'User', 'Friend' ) ) ) {
if ( $value['id'] == $userid ) {
$friendlist[$i]['Me'] = $value;
} else {
$friendlist[$i]['Friend'] = $value;
}
}
}
$i++;
}
$matches = array();
foreach ( $friendlist as $friend ) {
if ( stripos( $friend['Friend']['username'], $search ) !== false )
$matches[ $friend['Friend']['id'] ] = $friend['Friend']['username'];
}
asort( $matches );
$i = 0;
$newmatches = array();
foreach ( $matches as $key => $match ) {
$newmatches[$i]['Tag']['caption'] = $match;
$newmatches[$i]['Tag']['value'] = $key;
$newmatches[$i]['Tag']['image'] = $this->getProfileImage( $key );
$i++;
}
return $newmatches;
}