Laravel在哪里拥有

时间:2018-09-10 15:08:04

标签: php laravel laravel-5 eloquent

是否可以通过某种方式返回具有关系的父模型,但仅通过使用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在数组中的每个建筑物的所有房间。

4 个答案:

答案 0 :(得分:2)

首先,您需要知道,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个过滤室。

答案 1 :(得分:1)

$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();

希望这对您有所帮助。

答案 2 :(得分:0)

您可以使用以下代码执行此操作:

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

希望这会有所帮助。

答案 3 :(得分:0)

您可以渴望加载子关系并将建筑物从房间集合中移除:

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

要使其正常工作,您需要同时在Building和Room模型中声明该关系。