2013-04-27 101 views
3

我正在使用Laravel的雄辯ORM,並且在加載顯示項目時遇到問題。如何在Laravel中列出嵌套表中的所有項目

下面是這種情況:

  • 用戶關注的博客
  • 博客有文章

我有一個數據庫表命名的關係,這個表是用來存儲用戶ID和博客ID來顯示哪個用戶關注哪個Blog。我有一張描述博客的博客表格,我有一張表格。關係表將成爲我的數據透視表,將用戶與博客表連接在一起。現在,我需要列出用戶在列表中列出的所有博客中的所有帖子。

這裏是我的用戶模型:

public function following() { 
    return $this->has_many_and_belongs_to('Blog', 'relationships', 'user_id', 'blog_id'); 
} 

這裏是我的博客模式:

public function followers() { 
    return $this->has_many_and_belongs_to('User', 'relationships', 'blog_id', 'user_id'); 
} 
public function posts() { 
    return $this->has_many('Post'); 
} 

這是我正在試圖檢索列表中的帖子:

$posts = User::with(array('following', 'following.posts')) 
      ->find($user->id) 
      ->following() 
      ->take($count) 
      ->get(); 

此代碼只列出了實際的博客,我需要他們的帖子。

感謝您的幫助,如果您需要更多詳細信息,請告訴我。

SOLUTION:

我稍微修改下面的接受的答案,我決定使用JOIN減少SQL的數額的話費只需1個呼叫。這是它:

$posts = Post::join('blogs', 'posts.blog_id', '=', 'blogs.id') 
    ->join('relationships', 'blogs.id', '=', 'relationships.blog_id') 
    ->select('posts.*') 
    ->where('relationships.user_id', '=', $user->id) 
    ->order_by('posts.id', 'desc') 
    ->take($count) 
    ->get(); 

回答

3

這是本地雄辯方法無法實現的。但是你可以使用一些Fluent方法來加入這些表。例如:

編輯在這裏:我添加了渴望加載到Post查詢。

$user = User::find(1); 
$posts = Post::with('blog') // Eager loads the blog this post belongs to 
    ->join('blogs', 'blogs.id', '=', 'posts.blog_id') 
    ->join('relationships', 'relationships.blog_id', '=', 'blogs.id') 
    ->where('relationships.user_id', '=', $user->id) 
    ->order_by('posts.id', 'desc') // Latest post first. 
    ->limit(10) // Gets last 10 posts 
    ->get('posts.*'); 

foreach ($posts as $post) { 
    print($post->title); 
} 

如果您還需要的所有博客的列表,這些用戶是繼上顯示一個側邊欄,例如。您可以使用DYI而不是依靠Eloquent,這應該更快,更具可定製性。例如:

$user = User::with('following')->find(1); 

// This creates a dictionary for faster performance further ahead 
$dictionary = array(); 
foreach ($user->following as $blog) { 
    $dictionary[$blog->id] = $blog; 
} 

// Retrieves latest 10 posts from these blogs that he follows 
// Obs: Notice the array_keys here 
$posts = Post::where_in('blog_id', array_keys($blog_ids)) 
    ->order_by('posts.id', 'desc') 
    ->limit(10) 
    ->get(); 

// Hydrates all posts with their owning blogs. 
// This avoids loading the blogs twice and has no effect 
// on database records. It's just a helper for views. 
foreach ($posts as $post) { 
    $post->relationships['blog'] = $dictionary[$post->blog_id]; 
} 

上查看:

foreach ($user->following as $blog) { 
    print($blog->title); 
} 

foreach ($posts as $post) { 
    print($post->title . ' @'. $post->blog->title); 
} 
+0

什麼渴望加載表?因爲當我渴望加載User :: with(array('following','following.posts'))時,數組的帖子嵌套在裏面,我只是無法到達他們。 – Karl 2013-04-30 19:49:57

+0

當你這樣渴望加載時,Eloquent從數據庫查詢所有訂閱的博客及其帖子,這可能很快就會變成數千人。如果你想顯示用戶訂閱的博客帖子,讓我們說,像tumblr的儀表板,最好的方式將是我建議的。雖然,你可以像'Posts :: with('blog')'一樣進行逆向加載。我已經編輯了一些關於如何解決這個問題的建議。 – vFragosop 2013-04-30 20:46:25

+0

謝謝Vinicius!我嘗試了兩種解決方案,但首選JOIN以避免進行多個SQL查詢。因爲我們要加入表格,所以您不必急於加載博客關係。這個解決方案給了我最好的性能。我將我的解決方案的修改版本添加到我的答案中。再次感謝!授予聲譽! – Karl 2013-05-03 18:39:21

相關問題