我确信还有其他方法可以实现此目的,但一种解决方案是使用join
通过查询生成器。
如果您的表设置如下:
users
id
...
friends
id
user_id
friend_id
...
votes, comments and status_updates (3 tables)
id
user_id
....
In your User model:
class User extends Eloquent {
public function friends()
{
return $this->hasMany('Friend');
}
}
In your Friend model:
class Friend extends Eloquent {
public function user()
{
return $this->belongsTo('User');
}
}
然后,要收集 id 为 1 的用户的朋友的所有投票,您可以运行以下查询:
$user = User::find(1);
$friends_votes = $user->friends()
->with('user') // bring along details of the friend
->join('votes', 'votes.user_id', '=', 'friends.friend_id')
->get(['votes.*']); // exclude extra details from friends table
运行相同的join
为了comments
and status_updates
表。如果您希望投票、评论和 status_updates 位于一个按时间顺序排列的列表中,您可以将生成的三个集合合并为一个,然后对合并后的集合进行排序。
Edit
要在一个查询中获取投票、评论和状态更新,您可以构建每个查询,然后合并结果。不幸的是,如果我们使用 Eloquent,这似乎不起作用hasMany
关系 (查看此问题的评论 https://stackoverflow.com/questions/19050387/laravel-using-union-in-query-builder为了讨论这个问题)所以我们必须修改查询才能使用where
反而:
$friends_votes =
DB::table('friends')->where('friends.user_id','1')
->join('votes', 'votes.user_id', '=', 'friends.friend_id');
$friends_comments =
DB::table('friends')->where('friends.user_id','1')
->join('comments', 'comments.user_id', '=', 'friends.friend_id');
$friends_status_updates =
DB::table('status_updates')->where('status_updates.user_id','1')
->join('friends', 'status_updates.user_id', '=', 'friends.friend_id');
$friends_events =
$friends_votes
->union($friends_comments)
->union($friends_status_updates)
->get();
不过,此时我们的查询变得有点复杂,因此与额外表(如下面的 DefiniteIntegral 建议的那样)的多态关系可能是一个更好的主意。