2013-08-29 14 views
10

私は、モデルの作成者がFooモデルの結果をフィルタリングするクエリスコープメソッドを持っています。合併症は、著者が直接関連していないということです。Laravelクエリスコープ内の関連モデルのクエリ

FooはBarに属し、BarはUserに属します。 fooはユーザーに属している場合、私はこれを行うことができます:Fooのモデルは何のuser_idの列を持っていないし、代わりにbar_id列を持っているよう

public function scopeAuthorOnly($query, User $user) 
{ 
    return $query->whereuser_id($user->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

、またそれを確認してください。 – Arda

+2

これは、テーブルインデックスを使用してより効率的に作業するため、より良いですが、 - > select( "users。*")を追加することを忘れないでください。そうでなければlaravelは "id"または間違ったテーブルの他のフィールドを与えることができます。エラーがスローされます。 –

+0

これは、MySQLに悩まされている方が良いでしょう。他のエンジンでは、このようなクエリでエラーが発生することがあります。 OPは彼がどのDBエンジンを使用しているかは一度も言及しなかった – Arda

8

あなたはまた、この関係を利用して行うことができます(マニュアルに頼らずに合流する):

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

編集:今whereHas代わりLaravel(withの> = 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

メインクエリに影響を及ぼすために 'with'の代わりに' whereHas'を使用することに関する修正をありがとう。 – casafred

14

を使用でき関係を照会するスコープ内のwhereHas()

このモデルではusers()リレーション機能があるとします。

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

更新:あなたはまた、巣whereHas文ができます。現在Foobarという名前の関係を持っており、barusersと呼ばれる関係を持っている場合、それは以下のようになるだろう、それはこのようなものになるだろうこれは:

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

さらに詳しい情報:私はLaravelウェイの回答を掲載しているhere

+0

FooがBarに属し、BarがUserに属している解決策を質問しました。あなたの答えはFooがUserに直接属していると仮定しています。 – casafred

+0

@casafred True、私の答えを更新しました。ありがとう! – Arda

関連する問題