2013-08-29 48 views
10

我有一个查询范围方法,可以根据模型的作者过滤Foo模型的结果。并发症是作者不直接相关。在Laravel查询范围内查询相关模型

Foo属于Bar和Bar属于User。如果富属于用户,我可以做到这一点:

public function scopeAuthorOnly($query, User $user) 
{ 
    return $query->whereuser_id($user->id); 
} 

这显然为富模型没有user_id列,而是具有bar_id列将无法正常工作。不过,我不知道如何以过滤user_id的方式构建查询。

任何指针?

回答

4

找到了解决办法:

public function scopeAuthorOnly($query, User $user) 
{ 
    $query 
     ->join('bars', 'foos.bar_id', '=', 'bars.id') 
     ->join('users', 'bars.user_id', '=', 'users.id') 
     ->where('users.id', '=', $user->id); 

    return $query; 
} 
+0

我已经发布了Laravel路的答案,也请您检查。 – Arda

+2

这比哪里更好,因为它使用表索引并且工作效率更高,但是不要忘记添加 - > select(“users。*”),否则laravel可以给你“id”或者其他任何来自错误表的字段,并且不会错误将被抛出。 –

+0

如果你坚持使用MySQL,这会更好。其他引擎可能会导致此类查询出错。 OP从未提及他使用的是哪个数据库引擎。 – Arda

8

你也可以做到这一点使用关系(而不是诉诸手动连接):

public function scopeAuthorOnly($query, User $user) 
{ 
    $query->whereHas(array('Bar' => function($query) use($user){ 
       $query->where('user_id', '=', $user->id); 
      })); 
} 

编辑:现在使用的withwhereHas代替(Laravel> = 4.1只要)。感谢Arda的纠正。

编辑:在4.2 whereHas的语法已经改变,使得关系名称是参数1和封闭是参数2(而不是被传递作为数组):

public function scopeAuthorOnly($query, User $user) 
{ 
    $query->whereHas('Bar', function($query) use($user){ 
       $query->where('user_id', '=', $user->id); 
      }); 
} 
+1

这不会影响主查询过滤,但只会影响关系中的结果。 – Arda

+1

感谢您对使用'whereHas'而不是'with'影响主要查询的更正。 – casafred

14

可以使用whereHas()在查询关系的范围内。

让我们假设你在这个模型中有一个users()关系函数。然后,它会是这样的:

public function scopeAuthorOnly($query, User $user) 
{ 
    return $query->whereHas('users', function($q) use($user){ 
     $q->where('id', $user->id); 
    }); 
} 

更新:您还可以窝whereHas语句:如果当前Foo有一个名为bar关系,bar有一个名为users关系,它会像这样的:

public function scopeAuthorOnly($query, User $user) 
{ 
    return $query->whereHas('bar', function($q) use($user){ 
     return $q->whereHas('users', function($q2) use($user){ 
      $q2->where('id', $user->id); 
     }); 
    }); 
} 

更多信息:here

+0

问题要求解决方案,其中Foo属于Bar和Bar属于User。你的答案假设Foo直接属于用户。 – casafred

+0

@casafred真的,更新了我的答案。谢谢! – Arda