【问题标题】:Laravel Where In on Where HasLaravel 在哪里
【发布时间】:2018-09-10 23:39:28
【问题描述】:

有没有什么方法可以返回一个有关系的父模型,但只使用 where in 返回一些关系行?

这可能很混乱,让我解释一下。

目前我有 2 个模型,建筑物和房间,1 个建筑物可以有很多房间。

我希望能够传入一组房间 ID,并返回站点并且只返回数组中的房间。

这是我目前拥有的

if($request->input('ids') && !is_null($request->input('ids'))){
    $ids = explode(',',$request->input('ids'));

    //Exploded ids looks like this    "2,4,11,55,56"

    $buildings = Buildings::join('rooms')->whereIn('rooms.id',$ids)->get();
} else {
    $buildings = Buildings::whereHas('rooms')->get();
}

目前,这将返回所有具有 id 在 ids 数组中的房间的建筑物及其所有房间,最终返回具有 200 多个房间的建筑物。我需要它来返回建筑物,并且只返回该数组中具有 id 的房间。

这可能吗?

我知道我可以以相反的方式进行操作,将所有房间作为父级然后获取建筑物,但我需要建筑物作为父级,因为我正在运行这样的 foreach 并得到结果

foreach($buildings as $key => $building){
    <h1>{{$building->name}}</h1>
    foreach($building->rooms as $k => $room){
      <p>{{$room->name}}</p>
    }
}

如果那仍然令人困惑,真实世界的场景是我正在生成房间的 PDF。可以通过勾选房间列表中房间旁边的复选框来选择房间。然后,我需要能够传递房间 ID 数组,并获取包含其中一个房间的所有建筑物。然后获取房间 id 在数组中的每个建筑物的所有房间。

【问题讨论】:

    标签: php laravel laravel-5 eloquent


    【解决方案1】:

    首先你需要知道,whereHas 只过滤你的父结果而不是急切的加载关系。因此,您也需要在急切负载中应用该过滤器。像这样

    $ids = explode(',',$request->input('ids'));
    $buildings = Buildings::with(['rooms' => function($q) use ($ids) {
        $q->whereIn('id', $ids);
    }])->whereHas('rooms', function($q) use ($ids) {
        $q->whereIn('id', $ids);
    })->get();
    

    这里whereHas过滤建筑物并使用with过滤房间。

    【讨论】:

    • 太棒了,这很有意义!谢谢
    【解决方案2】:
    $ids = explode(',',$request->input('ids'));
    $building_ids = Room::whereIn('id',$ids)->pluck('building_id');
    $buildings_with_specific_rooms = Building::join('rooms', 'buildings.id', '=', 'rooms.building_id')->select('buildings.name', 'rooms.name')->whereIn('buildings.id', $building_ids)->whereIn('rooms.id', $ids)->get();
    

    希望对你有所帮助。

    【讨论】:

      【解决方案3】:

      你可以用下面的代码做到这一点:

      $ids = explode(',',$request->input('ids'));
      $buildings = Buildings::whereHas('rooms', function($q) use ($ids) {
          $q->whereIn('id', $ids);
      })->get();
      

      希望这会有所帮助。

      【讨论】:

      • 这不起作用,这仍然会返回站点的每个房间,前提是该站点有一个房间,其 id 位于数组中
      【解决方案4】:

      您可以预先加载子关系并将建筑物从房间集合中取出:

      $buildings = Room::with('building')
          ->with('building.room')
          ->whereIn('id', $ids)
          ->get()
          ->pluck('building');
      

      为此,您需要在 Building 和 Room 模型中声明关系。

      【讨论】:

      • 因为我需要在建筑物上运行一个 foreach,然后在建筑物的每个房间上运行一个 foreach。建筑物必须是父关系
      • 其他答案之一已经解决了我的问题,不过感谢您的帮助和建议!
      猜你喜欢
      • 2015-04-22
      • 2012-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-30
      • 2018-12-08
      • 2013-09-10
      相关资源
      最近更新 更多