2013-08-29 8 views
10

Ich verfüge über eine Abfragebereichsmethode, die die Ergebnisse in einem Foo-Modell vom Autor des Modells filtert. Die Komplikation ist, dass der Autor nicht direkt verwandt ist.Abfrage eines verwandten Modells innerhalb eines Laravel-Abfragebereichs

Foo gehört zu Bar und Bar gehört dem Benutzer. Wenn Foo auf Benutzer gehörte, konnte ich dies nur tun:

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

offensichtlich das wird nicht funktionieren, wie die Foo Modell keine user_id Spalte hat und stattdessen eine bar_id Spalte hat. Ich bin mir jedoch nicht sicher, wie ich die Abfrage so erstellen kann, dass die user_id gefiltert wird.

Irgendwelche Zeiger?

Antwort

4

eine Lösung gefunden:

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

ich eine Laravel-Wege Antwort gepostet haben, überprüfen Sie bitte auch, dass. – Arda

+2

Das ist besser als whereHas, weil es Tabellenindex verwendet und effizienter arbeitet, aber nicht vergessen hinzuzufügen -> select ("users. *") Andernfalls kann laravel Ihnen "id" oder jedes andere Feld aus falscher Tabelle geben, und nein Fehler wird ausgelöst. –

+0

Dies ist besser, wenn Sie mit MySQL festgefahren sind. Andere Engines können bei solchen Abfragen Fehler verursachen. OP hat nie erwähnt, welche DB-Engine er benutzt. – Arda

8

Sie können dies mit Beziehungen auch tun (ohne schließt sich auf manuelle Rückgriff):

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

Edit: jetzt whereHas statt with (Laravel mit> = 4.1 nur). Danke für die Korrektur Arda.

Edit: in 4.2 Die Syntax der whereHas geändert hat, so dass die Beziehung Name Parameter 1 und der Verschluss Parameter 2 (anstatt als Array übergeben):

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

Dies hat keinen Einfluss auf die Abfrage der Hauptabfrage, sondern nur auf die Ergebnisse in Relation. – Arda

+1

Danke für die Korrektur bezüglich der Verwendung von 'whereHas' anstelle von' with', um die Hauptabfrage zu beeinflussen. – casafred

14

Sie können mit whereHas() in Bereichen, um Beziehungen abzufragen.

Angenommen, Sie haben eine users() Relation Funktion in diesem Modell. Dann würde es so etwas wie dieses:

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

Update: Sie können auch Nest whereHas Aussagen: Wenn der aktuelle Foo eine Beziehung bar genannt hat, und bar hat eine Beziehung genannt users, es sein würde dies:

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

Weitere Informationen: here

+0

Die Frage nach einer Lösung, bei der Foo zu Bar und Bar gehört, gehört dem Benutzer. Ihre Antwort geht davon aus, dass Foo direkt dem Benutzer gehört. – casafred

+0

@casafred True, aktualisierte meine Antwort. Vielen Dank! – Arda

Verwandte Themen