如何为Laravel关系添加更多条件?
我有一个具有以下架构的“连接”表:如何为Laravel关系添加更多条件?,laravel,laravel-4,eloquent,relationship,Laravel,Laravel 4,Eloquent,Relationship,我有一个具有以下架构的“连接”表: id requestor_id (user_id) requested_id (user_id) 假设John Doe(请求者)连接到Jane Doe(请求者),Jonnie Doe(请求者)连接到John Doe(请求者)。要列出John Doe的所有关系我必须 inner join "connections" on "users"."id" = "connections"."requested_id" or "users"."id" = "
id
requestor_id (user_id)
requested_id (user_id)
假设John Doe(请求者)连接到Jane Doe(请求者),Jonnie Doe(请求者)连接到John Doe(请求者)。要列出John Doe的所有关系我必须
inner join "connections"
on "users"."id" = "connections"."requested_id"
or "users"."id" = "connections"."requestor_id"
但这在Laravel目前是不可能的,因为,好吧,这里没有
belongstomy->or()
方法,所以你怎么做呢?我已经设法解决了这个关系,并想出了一个临时解决方案:
public function connections()
{
$relation = $this
->belongsToMany(static::class, 'connections', 'requestor_id', 'requested_id')
->withTimestamps();
/// delete the already built inner join
$relation
->getQuery() // Eloquent\Builder
->getQuery() // Query\Builder
->joins = [];
/// create a new inner join with the needed or condition
$relation->getQuery()->getQuery()->join('connections', function($join)
{
$join->on('users.id','=','connections.requestor_id');
$join->orOn('users.id','=','connections.requested_id');
});
return $relation;
}
首先,您需要修复该解决方案,因为它不会返回正确的结果(检查下面的)。 第二,它不适用于急切加载,所以我不会使用它 也就是说,您可以创建扩展
belongTomany
的自定义关系,并在模型上调整关系方法,或者使用已有的方法
因此,让我首先提出一些建议,我会找到一个更好的方法(我会使用朋友而不是联系,以便更容易遵循):
现在,它非常易于使用、灵活,并允许快速加载:
$user = User::first();
$user->friends; // merged collection thanks to the accessor
$user->friendOf; // collection of my fans ;)
$user->friendsOfMine; // my idols
$users = User::with('friendOf', 'friendsOfMine')->get();
您的固定解决方案 问题是,仍然会有
where
子句,这将中断您的查询。因此,您需要将其移动到joinClause
并在那里再添加一个:
public function friends()
{
$relation = $this
->belongsToMany(static::class, 'friends', 'user_id', 'friend_id')
->withTimestamps();
// get underlying Query\Builder
$query = $relation->getQuery()->getQuery();
// get rid of wrong where and its bindings
$query->setBindings([])
$query->wheres = [];
// fetch and alter joinClause
$join = reset($query->joins);
$join->where('friends.user_id', '=', $this->getKey())
->orOn('users.id','=','friends.user_id')
->where('friends.friend_id', '=', $this->getKey());
// Now the join looks like this:
//
// $key = $this->getKey();
//
// $query->join('friends', function($join) use ($key)
// {
// $join->on('users.id', '=', 'friends.friend_id')
// ->where('friends.user_id', '=', $key)
// ->orOn('users.id', '=','friends.user_id')
// ->where('friends.friend_id', '=', $key);
// });
return $relation;
}
public function friends()
{
$relation = $this
->belongsToMany(static::class, 'friends', 'user_id', 'friend_id')
->withTimestamps();
// get underlying Query\Builder
$query = $relation->getQuery()->getQuery();
// get rid of wrong where and its bindings
$query->setBindings([])
$query->wheres = [];
// fetch and alter joinClause
$join = reset($query->joins);
$join->where('friends.user_id', '=', $this->getKey())
->orOn('users.id','=','friends.user_id')
->where('friends.friend_id', '=', $this->getKey());
// Now the join looks like this:
//
// $key = $this->getKey();
//
// $query->join('friends', function($join) use ($key)
// {
// $join->on('users.id', '=', 'friends.friend_id')
// ->where('friends.user_id', '=', $key)
// ->orOn('users.id', '=','friends.user_id')
// ->where('friends.friend_id', '=', $key);
// });
return $relation;
}