Laravel ORM友谊关系无重复



用雄辩来建立友谊关系的最佳方式是什么?我的表模式如下,我想定义一个关系,在这里我可以检索所有的朋友,如下所示。

<?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的许多自引用表的解决方案只有一种方式,即我可以从关系的两侧检索朋友,但我必须是两行,例如,如果用户1和3是朋友,那么在一行中user_id=3和friend_id=1,在下一行中反之亦然。(或者,如果我没有两行,我必须执行两个查询)。

您可以进行两次查找,并使用一个联合查询,因此只访问数据库一次。将所有这些放在一个自定义函数中:

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);  
  }
}

您不应该尝试将应该是两行的内容变成一行,但如果您要尝试这样做,那么您绝对不需要两次访问数据库:

select * from users where (user_id = :user_id and friend_id = :friend_id) or  (friend_id = :friend_id and user_id = :user_id)

在拉拉维尔,这将是:

Users::whereRaw('(user_id = ? and friend_id = ?) or (friend_id = ? and user_id = ?)', [            
    $user_id,
    $friend_id,
    $friend_id,
    $user_id
]);

你也可以做sub-wheres来对它们进行分组,但这有点复杂。

我建议您使用条件来加载您想要的

  • 在这个例子中,假设您使用query加载user_id和devil_id,条件是

    "从friendship中选择*,其中user_ID='$ID'或friend_ID='$sid'"

$id:是您要显示给他的朋友的用户id。

在PHP中用于加载结果的WHILE循环中,您可以通过设置条件来过滤resulet

while ... {
if (friendship['user_id'] == $id) {
$f_id = friendship['friend_id'] ;  }
// other instructionS...
else  {
$f_id = friendship['user_id'] ;  } 
// other instructionS...
}

在这种情况下,您将从两个表列加载数据,然后每次使用用户id筛选列,只让他朋友的id,该筛选器过去不会对用户说您是自己的朋友。

对不起,我用mysql来解释这个例子

最新更新