基于关系过滤的雄辩的`with()`

Posted

技术标签:

【中文标题】基于关系过滤的雄辩的`with()`【英文标题】:Eloquent `with()` with filtering based on relation 【发布时间】:2020-09-29 19:52:22 【问题描述】:

我有这张桌子。

这个模型关系,这个关系很好。

class Item extends Model


    public function translations()
    
        return $this->hasMany(ItemTranslations::class);
    

class ItemTranslation extends Model


    public function language()
    
        return $this->belongsTo(Language::class);
    


我需要返回带有翻译的项目列表,但只返回与特定语言相关的翻译。

我不能让这个查询工作,我得到每个项目的所有翻译,而不仅仅是用这个查询过滤的那个。结果不需要与翻译相关的语言。

$query = Item::query();

$query->with('translations')->when('language',function($query) use ($ISOlanguage) 
    return $query->where('languages.ISO_code', '=', $ISOlanguage);
);

return $query->paginate();

知道我可以让谁工作吗?谢谢!

【问题讨论】:

【参考方案1】:

所以你想要做的是限制急切加载

Item::with(["translations" => function ($query) use ($ISOlanguage) 
    $query->where('language.ISO_code', $ISOlanguage);
])->get();

https://laravel.com/docs/5.8/eloquent-relationships#constraining-eager-loads

【讨论】:

列出所有(或部分)项目时,还希望加载翻译,但只加载与特定语言相关的翻译 在我的示例中,您加载了所有translations,其中languages ISO_code 等于您的$ISOlanguage:或者您的意思是什么? 感谢您的回复,由于某些原因无法正常工作,我用整个查询更新了我的问题。我收到此错误:``` 未定义表:7 错误:缺少表“语言”第 1 行的 FROM 子句条目:...item_translations"."language_id" in (1, 2) 和 "language... ^ ( SQL: select * from "item_translations" where "item_translations"."language_id" in (1, 2) and "language"."ISO_code" = EN) `` 即使我使用languages 这是真正的表名,我也会遇到同样的问题 如果没有querypaginate,它是否适用于我在问题中的示例?如果是这样,您可以使用我的示例并将get() 替换为paginate()【参考方案2】:

终于搞定了

Item::with(['translations' => function($query) use ($ISOlanguage) 
   $query->whereHas('language', function($query) use ($ISOlanguage) 
       $query->where('ISO_code', '=', $ISOlanguage);
   );
])->get();

感谢@julian-s 的帮助!

【讨论】:

以上是关于基于关系过滤的雄辩的`with()`的主要内容,如果未能解决你的问题,请参考以下文章

如何基于 get() 雄辩数组进行过滤

Laravel - 雄辩的 ORM 关系查询

Laravel 查询构建器与雄辩的关系

在laravel [实现过滤器]中将多个表与雄辩和急切的加载一起加入

Laravel 7 雄辩的嵌套条件,用于使用枢轴进行过滤

雄辩的子查询中的 whereIn 函数不会过滤任何记录