【问题标题】:Query HasManyThrough Laravel relation retrieving related records通过 Laravel 关系查询 HasManyThrough 检索相关记录
【发布时间】:2017-11-18 14:28:34
【问题描述】:

考虑到 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

posts 中的 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;
});

而且我已经尝试在负载内部使用带有 where 的闭包。但它也没有奏效。结果是一样的。

【问题讨论】:

    标签: php laravel eloquent


    【解决方案1】:

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

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

    看看你得到了什么回报。

    【讨论】:

    • 但我想提供加载帖子的数据。哪里会做呢?我认为 whereHas 只是条件。
    • 我认为它会将加载的帖子返回给您,试一试,看看结果如何。我一直在参考这篇文章,顺便说一句:stackoverflow.com/questions/30231862/…
    • 帖子未加载。我猜想 where has 是延迟加载。我需要在雄辩的查询之后进行 foreach 并调用 $country->posts 来获取它并放入国家/地区。
    • 使用之后,如果我尝试访问它的关系 ($country->posts),我会得到与第一次尝试相同的结果。很多不连贯的帖子。
    • 尝试将 groupBy 添加到嵌套查询中,例如:$query->where('type_id', 100)->groupBy('posts.id')
    【解决方案2】:

    您必须使用withwhereHas 进行查询。 whereHas 将限制 Country 查询仅显示具有指定 id 帖子的国家,但不会在结果中加载这些帖子。然后with() 将在结果中急切加载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();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-18
      • 2023-03-09
      • 2021-07-23
      • 2021-07-25
      • 2018-03-18
      • 2020-10-14
      • 1970-01-01
      相关资源
      最近更新 更多