查询HasManyThrough Laravel关系检索相关记录

时间:2017-06-15 23:39:29

标签: php laravel eloquent

考虑到Laravel指南中的基本示例Has Many Through关系,我试图直接查询具有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是我的特例..

因此,我在国家模型中创建了一种关系,通过用户创建与帖子的关系。我希望实现的结果是国家列表以及每个国家/地区内该国家/地区用户创建的帖子。

//Country.php
public function posts()
{
    return $this->hasManyThrough(
        'Post', 'User', 'country_id', 'user_id'
    );
}

我能够以其他方式复制我想要实现的结果,但我想知道为什么下面的雄辩查询不会返回预期的结果:

   $postsGroupedByCountries = Country::with([
        'posts' => function ($query) {
            $query->where('type_id', 100);
        }
    ])->get();

查询的返回是几个国家,所有帖子都没有数据。使用Laravel Eloquent进行此查询的正确方法是什么?

首先尝试:

$postsGroupedByCountries = Country::whereHas('posts', function ($query) {
    $query->where('type_id', 100);
})->get();

第二次尝试:

$postsGroupedByCountries = Country::whereHas('posts', function ($query) {
    $query->where('type_id', 100)->groupBy('posts.id');
})->get();

第三次尝试:

$postsGroupedByCountries = Country::whereHas('posts', function ($query) {
    $query->where('type_id', 100);
})->get();

$postsGroupedByCountries = $postsGroupedByCountries ->map(function($country){
     $country->load('posts');
     return $country;
});

我已经尝试过在负载内部使用闭合装置。但它也没有用。结果是一样的。

2 个答案:

答案 0 :(得分:3)

您必须使用withwhereHas进行查询。 whereHas会限制Country查询仅显示包含指定ID的帖子的国家/地区,但不会在结果中加载这些帖子。然后,with()会在结果BUT中急切加载posts,因为它在第一个查询执行后被调用,因为它不知道whereHas约束,并且由于它已经传递了没有约束,它将会加载每个国家/地区的所有帖子。要使用相同的约束加载Country个帖子,您需要将其传递给with方法。

所有放在一起看起来像:

$countries = Country::whereHas('posts', function($query) {
    return $query->where('type_id', 100);
})
->with(['posts' => function($query) {
    return $query->where('type_id', 100);
}])
->get();

答案 1 :(得分:1)

您渴望加载每个国家/地区的所有帖子,这就是您全部看到它们的原因。我会尝试将查询修改为:

$postsGroupedByCountries = Country::whereHas('posts', function ($query) {
    $query->where('type_id', 100)
})->get();

看看你得到了什么。