#laravel #laravel-5 #eloquent
#laravel #laravel-5 #красноречивый
Вопрос:
Попытка получить отель в деталях для API управления отелем, в котором для некоторых отелей получение
$отель-> номера
как объекта, а для некоторых как массива. Запрос eloquent в модели отеля, как показано ниже.
public function detail($hotelid) {
return $this->with(['rooms','roomType'])->find($hotelid);
}
public function rooms() {
return $this->hasMany(HotelRooms::class, 'hotels_id')->where('status','active');
}
Модель гостиничного номера
public function roomType(){
return $this->hasOne(RoomType::class,'id','room_type_id')->where('status','active');
}
Контроллер
public function __construct(){
$this->model = new Hotel();
}
public function hotelDetail(Request $request){
$data = $this->model->detail($request->input('hotel_id'));
foreach($data->rooms as $key=>$room){
if(!$room->roomType){
unset($data->rooms[$key]);
continue;
}
}
return response()->json([
'status' => true,
'status_message' => 'successful',
'data' => $data,
]);
}
ответ
{
"id":"id",
"name":"name",
"rooms":{
"1":{},
"2":{}
}
}
{
"id":"id",
"name":"name",
"rooms":[
{},
{},
]
}
Комментарии:
1. Что у вас получилось? и чего же вы ожидаете?
2. В ответ я получил и то, и другое. Например, для hotel-1 я получил первый ответ, а для hotel-2 — второй. Я предпочитаю второй ответ @hoseinz3
3. Пожалуйста, поделитесь своим определением отношения комнат
4. Пожалуйста, не могли бы вы добавить свой метод контроллера?
5. Я думаю, что в методе detail вы попробовали некоторую фильтрацию, после использования
filter
метода вам следует добавитьvalues
метод для переиндексации ответа
Ответ №1:
Когда вы используете unset
on array, индексы вашего массива сохраняются для каждого элемента. То же, что для collection->filter()
или для array_filter()
того, что фактически используется в collection->filter()
. Вот почему вам нужно перестроить индексы:
$data->rooms = array_values($data->rooms->toArray());
для переиндексации массива.
Или используйте foreach
, но помещайте значения в новый массив:
$filteredRooms = [];
foreach($data->rooms as $key=>$room){
if(!$room->roomType){
continue;
}
$filteredRooms[] = $room;
}
$data->rooms = $filteredRooms;
Или вместо foreach
цикла используйте filter
для сбора в сочетании с values()
:
$filteredRooms = $data->rooms->filter(function ($room, $key) {
return (!$room->roomType)? false : true;
})->values();
Комментарии:
1.
... "rooms": { "1": { "id": 2,...
2. @NoName, это заменяет foreach . Вы можете переназначить значение на
$data->rooms = $filteredRooms
после3.
$data->rooms = array_values($data->rooms->toArray());
протестировал это @nikalz4. это работает
unset($data->rooms); $data->rooms = $fileteredRooms;
после foreach. Где в foreach$filteredRooms[]=$room
.5. когда вы используете unset , индексы вашего массива сохраняются для каждого элемента, такие же, как для collection-> filter() или для array_filter(), который фактически используется в collection-> filter(). Вот почему вам нужно перестроить индексы любым способом, предложенным в ответе выше
Ответ №2:
После фильтрации массива вам необходимо повторно проиндексировать свой массив.
foreach($data->rooms as $key=>$room){
if(!$room->roomType){
unset($data->rooms[$key]);
continue;
}
}
$data->rooms = $data->rooms->values();
Комментарии:
1. получение того же ответа
2. но получение в виде массива при добавлении последней строки внутри foreach, это правильный формат?