Laravel - 雄辩的 ORM 关系查询

Posted

技术标签:

【中文标题】Laravel - 雄辩的 ORM 关系查询【英文标题】:Laravel - Eloquent ORM Relationship Query 【发布时间】:2016-02-26 13:20:51 【问题描述】:

我有 5 张桌子:

 1. news
 2. tags
 3. filters
 4. news_tag
 5. tag_filters

表结构如下:

新闻

id
title
description

标签

id
title

过滤器

id
title

news_tag

id
tag_id
news_id

tag_filter

id
tag_id
filter_id

假设我的表有以下记录:

news: id = 1 title = News_1 Description = Details for News_1
tags: id = 1 title = php
filters: id = 1 title = PHP News
news_tag: id = 1 tag_id = 1 news_id = 1
tag_filter: id = 1 tag_id = 1 filter_id = 1

我的模型中的关系如下:

新闻模型

public function tags()

    return $this->belongsToMany('App\Tag', 'news_tag');

标签模型

public function news()

    return $this->belongsToMany('App\News', 'news_tag');
 

public function filters()

    return $this->belongsToMany('App\Filter', 'tag_filter');

过滤器模型

public function tags()

    return $this->belongsToMany('App\Tag', 'tag_filter');

假设我的路线如下:Route::get('news/filter/filter_id','NewsController@getNews');

当我将 filter_id 1 传递给我的路线时,我想检索与 tag_id 1 相关的所有新闻。任何人都可以帮助我如何在我的控制器中执行此操作?

【问题讨论】:

【参考方案1】:

没有简单的方法可以做到这一点,但您可以使用以下方法:

News::select("news.*")
  ->join('tags'...)
  ->join('filters'...)
  ->where('filter_id',...)
  ->where('tag_id',...)
  ->get();

注意select() 指令。如果你跳过它,Laravel 会将无效字段加载到你的 News 模型中。当你在 Eloquent Builder 中加入时,它是必备的。

如果您想在这种情况下预先加载关系,请使用查询构建器的with() 方法。

【讨论】:

您能详细说明一下加盟条件和条件吗?问题是 tag_id 与 news_id 相关。所以基本上我需要获取与传递给我的路由的 filter_id 相关的所有 tag_ids,然后查找与这些 tag_ids 相关的所有 news_ids。【参考方案2】:

你可以尝试一些嵌套的 whereHas 来代替 join。我不确定性能。

    $filterId = 1;
    News::whereHas('tags', function($q1) use ($filterId) 
        $q1->whereHas('filters', function($q2) use ($filterId) 
            $q2->where('id', '=', $filterId);
        );
    );

【讨论】:

它can be slow.

以上是关于Laravel - 雄辩的 ORM 关系查询的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 5.2 中雄辩的 ORM 同表关系

laravel 4 - 如何限制(采取和跳过)雄辩的 ORM?

Laravel 雄辩的 ORM 群在哪里

Laravel 雄辩的一对一通过(级别/树)关系

laravel 雄辩的关系查询

orWhere 不使用 Laravel 雄辩的关系查询