2016-05-23 77 views
2

目前我正致力于一个多域和语言项目,其中视频可以重复使用不同的标题和描述。Laravel 5.2 |多对多查询

我的表是有关这个问题有关系,看起来像

posts >- videos >- videos_tags -< tags 
id    id    id     id 
domain_id      video_id    
video_id      tag_id 

当然,我所创建的模型:邮政,视频和标签与所有需要的关系。

我想要的是通过我的标记模型获取所有帖子并保持分页()功能。

我能够通过视频模型获取链接到帖子的所有标签。但是,当我尝试一种相反的方式,我似乎并没有保持分页()功能。我尝试了很多,但似乎找不到合适的解决方案。

最接近的(我认为)我已经与这一段代码:

// App\Models\Tag 
public function posts() 
{ 
    $posts = []; 

    foreach ($this->videos as $video) 
    { 
     foreach ($video->posts as $post) 
     { 
      if (!array_key_exists($post->id, $posts)) $posts[$post->id] = $post; 
     } 
    } 


    return \Illuminate\Database\Eloquent\Collection::make($posts); 
} 

我寻求答案时我已经错过任何建议或文章,欢迎:)询问后

回答

2

直接这个问题我有一个尤里卡时刻,并找到了解决方案。做到这一点的方法不是通过标签模型获取Post模型,而是通过Post模型本身。

这是我做过什么:

// App\Models\Tag 
public function posts() 
{ 

    return Post 

      ::select('posts.*') 

      ->join('videos', 'posts.video_id', '=', 'videos.id') 

      ->join('videos_tags', 'videos.id', '=', 'videos_tags.video_id') 

      ->join('tags', 'videos_tags.tag_id', '=', 'tags.id') 

      ->where('tags.id', $this->id); 

} 

这解决了查询多对多的一一对应关系,并在执行查询之前保持eloquents功能的问题。

1

你可以在你的帖子模型中定义一个所谓的作用域。

class Post { 
    /** 
    * Limit query to posts related to a given tag id. 
    * 
    * @param Builder $query The original query 
    * @param Integer $tag_id The tag id to filter for 
    * @return Builder   The query with an additional where 
    */ 
    public function scopeHasTag($query, $tag_id) 
    { 
     // assumes that there is a 'tags' relation 
     return $query->whereHas('tags', function($tags_query) use ($tag_id) { 
      return $tags_query->where('id', $tag_id); 
     }); 
    } 
} 

此范围将允许您执行类似下面的查询(hasTags是laramagically从scopeHasTags得出)。

$posts = Post::query()->hasTag(10); // All posts related with tag id 10 
return $posts->paginate(); 

这里是有关查询范围的官方文档:https://laravel.com/docs/5.2/eloquent#local-scopes

+0

感谢您的回答!我从来没有想过使用范围。这是一个不错的选择,我一定会试一试。 –