2014-04-04 11 views
11

Ich versuche, Eager-Loading verschachtelten Beziehungen, mit Einschränkungen, zu arbeiten. Jeder scheint das gleiche Beispiel von eifrigen Lade verschachtelte Beziehungen zu geben:Laravel 4.1 Eager Laden geschachtelte Beziehungen mit Einschränkungen

$users = User::with('posts.comments')->get(); 

Was ich stattdessen tun möchte, ist zu bekommen, die alle im Zusammenhang Benutzer auf einen Posten einer bestimmten ID. Gleichzeitig möchte ich aber auch die Kommentare zu diesem Beitrag erhalten.

In 4.1, ich letzteres zu erreichen, könnte ich tun:

$comments = Comment::whereHas('post', function($query) { $query->whereId(1); })->get(); 

Gibt es eine Möglichkeit, diese beiden zu heiraten und eine verschachtelte Beziehung zu beschränken?

Antwort

8

Eigentlich fand es ein Viel einfacher als gedacht.

Da diese Modelle:

class User extends \Eloquent { 

    public function posts() 
    { 
     return $this->hasMany('Post'); 
    } 

    public function comments() 
    { 
     return $this->hasManyThrough('Comment', 'Post'); 
    }  

} 

class Post extends \Eloquent { 

    public function user() 
    { 
     return $this->belongsTo('User'); 
    } 

    public function comments() 
    { 
     return $this->hasMany('Comment'); 
    }  

} 

class Comment extends \Eloquent { 

    public function post() 
    { 
     return $this->belongsTo('Post'); 
    } 

} 

Wir können dann einen Benutzer holen, die einen bestimmten Beitrag hat etwa so:

$userId = 2; $postId = 5; 
$user = User::with(['comments' => function($q) use($postId) { $q->where('post_id', $postId); }])->find($userId); 

Das wird nicht funktionieren, wenn get() verwenden, da es nicht der Fall ist Beschränken Sie die Benutzer auf nur diejenigen, die sich auf den angegebenen Beitrag beziehen. Aber das ist in Ordnung, da wir nur an einem Post von post_id $ postId interessiert sind. Da ein Post zu einem einzigen Benutzer gehört, müssen wir uns nicht um die anderen Benutzer kümmern. Wir könnten daher find() oder first() verwenden, um die tatsächlichen Ergebnisse zu erhalten.

Auch die ‚Mitte‘ Beziehung dh ‚post‘ wird automatisch zurückgegeben und wir können es erhalten, indem Sie die folgenden Aktionen ausführen, ohne eine zusätzliche ‚mit‘ verwenden, wie sie in früheren Antwort vorgeschlagen:

var_dump($user->posts); 
3

Es ist schwer, dass im Rahmen von User-> post-> Kommentar zu erreichen, aber Sie können dies ganz einfach von Post starten, wenn dieses zusagt:

Post::with('users')->with('comments')->find(1); 

, da es alle Benutzer geladen werden und alle Kommentare zu dem angegebenen Beitrag.

- bearbeiten: Seien Sie nicht den ersten Satz vertrauen, als dies so einfach ist:

// $id of the post you want 

User::with(['comments' => function ($q) { // this is hasManyThrough relation 
    $q->where('post_id',$id);    // comments only related to given post 
}])->with(['posts' => function ($q) { 
    $q->whereId($id);      // here we load only the post you want 
}])->whereHas('posts', function ($q) { 
    $q->whereId(1);       // here we filter users by the post 
})->get(); 

Geist aber, dass Laravel 3 Abfragen ausgeführt werden, um es

getan
+0

Ich bemerkte gerade, dass ich ein Benutzerobjekt zurückgegeben haben muss, weil mein Controller (und Ansicht) ein Benutzerobjekt erwartet. Es würde eine Menge kosten, danach noch einmal zu prüfen, um welches Objekt es sich handelt. – kJamesy

+0

bearbeitet, überprüfen Sie es jetzt –

+0

Danke für Ihre Eingabe. Es wurde festgestellt, dass wir das zusätzliche 'mit' oder 'woHas' nicht verwenden müssen. Wenn wir es dort beenden ('post_id', $ id '), werden wir alles geben, was wir brauchen. Und da ein Post nur einem Benutzer gehört, sollten wir find() oder first() anstelle von get() verwenden. – kJamesy

7

Wenn die Beziehungen in den Modellen korrekt sind Sie einfach tun:

$user = User::with('posts.comments')->get(); 

Sie so viele Beziehungen hinzufügen können, wie Sie (oder bis zur Speichergrenze;) wollen).

Es funktioniert auch mit Pivot-Tabellen.

+0

Ich habe Sie abgelehnt, weil Sie die Frage nicht wirklich gelesen haben. Die Antwort, die Sie gegeben haben, wird in der Frage tatsächlich als die falsche Antwort vorgeschlagen. – kJamesy

+0

Ich wollte nur erwähnen, dass die Beziehungsmethode im Modell "öffentlich", nicht "geschützt" oder "privat" sein muss. (Ich gehe normalerweise mit "geschützt") – IIllIIll