【问题标题】:Laravel 5.2 | query many to many to oneLaravel 5.2 |查询多对多对一
【发布时间】:2016-05-23 23:03:08
【问题描述】:

目前我正在开展一个多领域和多语言项目,在该项目中以不同的标题和描述重复使用视频。

我的与这个问题相关的表格看起来像

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

当然,我已经创建了模型:帖子、视频和标签以及所有必需的关系。

我正在尝试通过我的 Tag 模型获取所有帖子并维护 pagination() 功能。

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

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

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

欢迎我在寻求答案过程中错过的任何建议或文章 :)

【问题讨论】:

    标签: php laravel eloquent


    【解决方案1】:

    问完这个问题后,我突然灵光一现,找到了解决方案。一种方法不是通过 Tag 模型获取 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 功能。

    【讨论】:

      【解决方案2】:

      您可以在 Posts 模型上定义所谓的范围。

      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 是从 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

      【讨论】:

      • 感谢您的回答!我从来没有想过使用范围。这是一个不错的选择,我一定会试试你的答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-30
      • 2018-06-07
      • 1970-01-01
      • 1970-01-01
      • 2020-07-01
      • 1970-01-01
      相关资源
      最近更新 更多