Laravel ORM 友谊关系不重复
Posted
技术标签:
【中文标题】Laravel ORM 友谊关系不重复【英文标题】:Laravel ORM Friendship Relationship without duplication 【发布时间】:2013-07-24 18:10:02 【问题描述】:与 eloquent 建立友谊关系的最佳方式是什么?我的表架构如下,我想定义一个关系,我可以在其中检索所有朋友,如下所示。
<?php
class User extends Eloquent
public function friends()
return $this->belongsToMany('User', 'friendships', 'user_id', 'friend_id')->orWhere($this->id,'=', 'friend_id');
+----+---------+-----------+----------+---------------------+---------------------+
| id | user_id | friend_id | state | created_at | updated_at |
+----+---------+-----------+----------+---------------------+---------------------+
| 1 | 3 | 1 | accepted | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 |
| 2 | 2 | 3 | accepted | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 |
+----+---------+-----------+----------+---------------------+---------------------+
当我寻找用户 ID 为 3 的朋友时,上面的关系接近工作我得到用户 1 和 3,但显然我想要 1 和 2。
友谊表
user_id:请求友谊的用户 ID friend_id:目标好友的用户 ID state:友谊是挂起、接受还是阻止。 created_at 和 updated_at
我知道Laravel Many to many self referencing table only works one way 提供了一些解决方案,我可以在其中检索关系双方的朋友,但我必须是两行,例如如果用户 1 和 3 是朋友,那么在一行中 user_id = 3和friend_id = 1,在下一行反之亦然。 (或者如果我没有两行,我必须做两个查询)。
【问题讨论】:
【参考方案1】:您可以进行两次查找,and use a union query,因此只访问数据库一次。将所有这些放在自定义函数中:
class User extends Eloquent
public function friends()
$first = $this->belongsToMany('User', 'friendships', 'user_id', 'friend_id');
return $this->belongsToMany('User', 'friendships', 'friend_id', 'user_id')->union($first);
【讨论】:
谢谢这看起来正是我想要的但是我得到了这个错误参数 1 传递给 Illuminate\Database\Query\Builder::mergeBindings() 必须是 Illuminate\Database\Query\Builder 的一个实例,给定的 Illuminate\Database\Eloquent\Relations\BelongsToMany 实例,在第 857 行的 /var/www/cc/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php 中调用并定义【参考方案2】:我有一个建议,你可以使用条件来加载你想要的值
在这个例子中,假设你使用查询来加载 user_id 和 fiend_id 的条件,
" select * fromfriendship WHERE user_ID = '$id' ORfriend_ID = '$id' "
$id : 是你想给他的朋友看的用户ID。
在 PHP 中的 WHILE 循环中,您将使用它来加载结果,您可以通过设置条件来过滤结果
while ...
if (friendship['user_id'] == $id)
$f_id = friendship['friend_id'] ;
// other instructionS...
else
$f_id = friendship['user_id'] ;
// other instructionS...
在这种情况下,您将从两个表列中加载数据,然后每次使用用户 id 过滤列,只让他的朋友的 id ,过滤器过去不会告诉用户您是自己的朋友。
对不起,我用mysql来解释例子
【讨论】:
我不确定如何在 Eloquent 中使用它?【参考方案3】:您不应该尝试将应该是两行的内容变成一行,但如果您要尝试这样做,那么您绝对不需要两次访问数据库:
select * from users where (user_id = :user_id and friend_id = :friend_id) or (friend_id = :friend_id and user_id = :user_id)
在 Laravel 中应该是:
Users::whereRaw('(user_id = ? and friend_id = ?) or (friend_id = ? and user_id = ?)', [
$user_id,
$friend_id,
$friend_id,
$user_id
]);
您也可以使用 sub-where 来对它们进行分组,但这有点复杂。
【讨论】:
以上是关于Laravel ORM 友谊关系不重复的主要内容,如果未能解决你的问题,请参考以下文章
Laravel 4:如何使用 Eloquent ORM“排序”[重复]