具有 HasMany 关系的筛选器模型



假设我有两个模型:ParkItems。每个Park都可以通过HasMany关系Items

Items桌子上有一个park_id场和一个type旗:Item可以是喷泉,篮球场或其他任何东西。

我需要做的是过滤公园,以仅获取那些在数组中传递了所有项目类型的公园。这是我所拥有的:

$parks = Park::whereHas('items', function($q) use ($request) {
            $q->where('type', json_decode($request->type_list));
        })->get();

但它无法正常工作。有什么想法吗?

非常感谢,祝大家新年快乐!

编辑:我找到了一个可行的解决方案,尽管非常丑陋:

$types_array = json_decode($request->type_list, true);
$results = [];
// A collection of parks for each item type
foreach($types_array as $type) {
    $results[] = Park::whereHas('items', function($q) use ($type) {
        $q->where('type', $type);
    })->get();
}
// Intersect all collections
$parks = $results[0];
array_shift($results);
foreach ($results as $collection) {
    $parks = $collection->intersect($parks);
}
return $parks;

您可以在wherehas方法中使用foreach。它应该是这样的:

$array = json_decode($request->type_list, true)
$parks = Park::whereHas('items', function($q) use ($array) {
             foreach ($array as $key => $type) {
                 $q->where('type', $type);
             }
         })->get();
我认为使用

where 子句匹配同一行的所有项目类型不会产生任何结果,这就像做where id = 1 and id = 2这是不可能的,因为 id 只能取一个值,你应该做的是使用 whereIn 获取至少匹配一种类型的所有项目,然后使用 groupBypark_id对结果进行分组, 然后在 HAVING 子句中,您可以检查组计数是否等于type_list计数:

$types = json_decode($request->type_list, true);
$parks = Park::whereHas('items', function($q) use ($types) {
    $q->select('park_id', DB::raw('COUNT(park_id)'))
      ->whereIn('type', $types)
      ->groupBy('park_id')
      ->havingRaw('COUNT(park_id) = ?', [ count($types) ]);
})->get();

您可以向一个查询添加多个whereHas()约束:

$types_array = json_decode($request->type_list, true);
$query = Park::query();
foreach($types_array as $type) {
    $query->whereHas('items', function($q) use($type) {
        $q->where('type', $type);
    });
}
$parks = $query->get();

相关内容

  • 没有找到相关文章

最新更新