2014-04-04 16 views
11

Eager-Loading iç içe geçmiş ilişkileri, kısıtlamalarla çalışmak için çalışıyorum. Bunun yerine ne yapmak istiyorumLaravel 4.1 İstenmeyen Yüklemelerle İç İçe İlişkiler Yüklüyor

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

verilen bir kimliği bir yazı ile ilgili tüm Kullanıcıları olsun: Herkes hevesli yüklemeli iç içe ilişkilerin aynı örneği vermek gibi görünüyor. Ancak aynı zamanda, bu gönderi ile ilişkili yorumları almak istiyorum.

4.1, ben ikinci elde etmek, elimden:

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

yuvalanmış bir ilişki bu iki evlenmek ve sınırlamak için bir yolu var mı?

cevap

8

Aslında buldum o düşünmekten daha basit.

Verilen bu modeller: Bu ETMEZ olarak get() kullanılırken bu işe yaramaz

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

:

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

} 

Sonra şöyle verilen bir yazı olan bir kullanıcı getirebilir Kullanıcıları yalnızca belirtilen gönderi ile ilgili olanlarla sınırlandırın. Ancak bu sadece bir post_id $ postId tek bir gönderiyle ilgilendiğimiz için sorun değil. Bir gönderi bir ve bir kullanıcı için ait olduğundan, diğer kullanıcılar için endişelenmemize gerek yok. Bu nedenle, gerçek sonuçları almak için find() veya first() kullanabiliriz. Ayrıca

, 'orta' ilişki yani 'post' otomatik döndürülür ve önceki yanıtta önerildiği gibi biz 'ile' ekstra kullanmak zorunda kalmadan aşağıdakileri yaparak bunu elde edebilirsiniz:

var_dump($user->posts); 
3

Bu Kullanıcı-> Post-> Yorum bağlamında Bunu başarmak zor, ancak kolayca Post'tan başlayan yapabilirsiniz eğer bu takım elbise size:

Post::with('users')->with('comments')->find(1); 
tüm kullanıcılara yükleyecektir olarak

ve tüm verilen yayına ilişkin yorumlar.

- düzenleme: ilk cümleyi güvenme, bu kadar basit:

// $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(); 

Zihin o laravel 3 sorguları

halletmek için çalışacaktır gerçi
+0

Denetleyicimin (ve görünümün) bir kullanıcı nesnesi beklemesi nedeniyle bir kullanıcı nesnesinin döndürülmesi gerektiğini fark ettim. Hangi nesneyi belirlemek için daha sonra başka bir kontrol yapmak çok masraflı olacaktır. – kJamesy

+0

düzenlenmiş, şimdi kontrol et –

+0

Girişiniz için teşekkürler. Fazladan 'ile' veya 'whereHas'i kullanmamız gerekmediğini keşfettik. Onu ('post_id', $ id ') nerede sonlandırmamız gerektiği için bize gereken her şeyi verecektir. Bir gönderi yalnızca bir kullanıcıya ait olduğundan, get() yerine find() veya first() işlevini kullanmalıyız. – kJamesy

7

ise modellerinde ilişkiler sadece yapabileceği doğru:

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

istediğiniz kadar ilişkilerini eklemek (veya hafıza sınırına kadar;) olabilir).

Ayrıca pivot tablolarla çalışır.

+0

Sizi oyalamadım çünkü soruyu gerçekten okumadınız. Verdiğiniz cevap, aslında yanlış cevap olarak sorulan sorular arasındadır. – kJamesy

+0

Ayrıca sadece modeldeki ilişki metodunun “public”, “korumalı” ve “private” olmaması gerektiğini belirtmek istedim. (Genellikle "korumalı" ile giderim) – IIllIIll