2013-08-29 77 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