[英]Query HasManyThrough Laravel relation retrieving related records
Considering the basic example Has Many Through relationship in the Laravel guide, I'm trying to query directly with eloquent, countries with posts from type 100 (just an example).考虑到 Laravel 指南中的基本示例 Has Many Through 关系,我尝试使用 eloquent 直接查询,这些国家的帖子来自类型 100(只是一个示例)。
countries
id - integer
name - string
users
id - integer
country_id - integer
name - string
posts
id - integer
user_id - integer
title - string
type_id - integer
type_id in posts is my peculiar case..帖子中的 type_id 是我的特殊情况..
So, I created a relationship in the country model that creates a relation with posts through users.因此,我在国家 model 中创建了一个关系,该关系通过用户创建了与帖子的关系。 The result that I want to achieve is a list of countries and within each country the posts created by users of that country.我想要实现的结果是一个国家列表以及每个国家/地区内该国家/地区用户创建的帖子。
//Country.php
public function posts()
{
return $this->hasManyThrough(
'Post', 'User', 'country_id', 'user_id'
);
}
I was able to replicate the result I want to achieve in other ways, but I would like to know why the eloquent query below does not return the expected result:我能够以其他方式复制我想要实现的结果,但我想知道为什么下面的 eloquent 查询没有返回预期的结果:
$postsGroupedByCountries = Country::with([
'posts' => function ($query) {
$query->where('type_id', 100);
}
])->get();
The return of the query are several countries with all posts without data.查询的返回是几个国家,所有帖子都没有数据。 What is the correct way to do this query with Laravel Eloquent?使用 Laravel Eloquent 执行此查询的正确方法是什么?
First try:第一次尝试:
$postsGroupedByCountries = Country::whereHas('posts', function ($query) {
$query->where('type_id', 100);
})->get();
Second try:第二次尝试:
$postsGroupedByCountries = Country::whereHas('posts', function ($query) {
$query->where('type_id', 100)->groupBy('posts.id');
})->get();
Third try:第三次尝试:
$postsGroupedByCountries = Country::whereHas('posts', function ($query) {
$query->where('type_id', 100);
})->get();
$postsGroupedByCountries = $postsGroupedByCountries ->map(function($country){
$country->load('posts');
return $country;
});
And I've already tried inside the load to use a closure with where as well.而且我已经尝试在负载内部也使用带有 where 的闭包。 But it also did not work.但它也没有奏效。 The result is the same.结果是一样的。
You have to use with
and whereHas
for the query. 您必须使用with
和whereHas
进行查询。 whereHas
is going to constrain the Country
query to only show countries with posts from the specified id but does not load those posts in the results. whereHas
将限制Country
查询仅显示具有指定id的帖子的国家,但不会在结果中加载这些帖子。 with()
will then eager load the posts
in the results BUT since it is called after the first query executes it does not know about the whereHas
constraint and since it has been passed no constraints it will load all of the posts for each country. 然后with()
会急切加载结果中的posts
但因为它在第一个查询执行后调用它不知道whereHas
约束,并且由于它没有传递任何约束,它将加载每个国家的所有帖子。 To load the Country
's posts with the same constraints you would need to pass that to the with
method as well. 要使用相同的约束加载Country
的帖子,您还需要将其传递给with
方法。
All put together it would look like: 所有放在一起看起来像:
$countries = Country::whereHas('posts', function($query) {
return $query->where('type_id', 100);
})
->with(['posts' => function($query) {
return $query->where('type_id', 100);
}])
->get();
You are eager loading all the posts with every country, that is why you're seeing them all. 你渴望加载每个国家的所有帖子,这就是你看到它们的原因。 I would try modifying the query to this: 我会尝试将查询修改为:
$postsGroupedByCountries = Country::whereHas('posts', function ($query) {
$query->where('type_id', 100)
})->get();
See what that gets you returned. 看看你得到了什么。
// Country.php
public function postsOfTypeHundred()
{
return $this->hasManyThrough('Post', 'User', 'country_id', 'user_id')
->where('type_id', 100);
}
/**
* Laravel ^9.15
* In Controller
*/
$countries = Country::withWhereHas('postsOfTypeHundred')->get();
/** Created By */
$countries[0]->posts[0]->user->name
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.