2013-04-27 126 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

相关问题