Laravel Eloquent разбивает большой запрос на фрагменты и использует их повторно

У меня действительно очень большое формирование запросов, как показано ниже. Я хочу разделить это и нужно повторно использовать для многих других вызовов AJAX

$buildquery=Hotel::has('room');

$buildquery->whereHas('room', function($query) use ($request) {

// If amenities is there add it to query
if($request->filled('amenities')){
$amenities = $request->amenities;
$count = count($amenities);

$query->withCount(['amenities' => function($query) use ($amenities, $count){
$query->whereIn('amenities_id', $amenities);
}])
->having('amenities_count', $count);
}

/* filter based on guest */

if($request->filled('guestsCount')){
$memberCount = $request->guestsCount + $request->childCount;
$query->Where('capacity', '>=',  $memberCount);
}else{
$query->Where('capacity', '>=',  1);
}
});

$buildquery->with(['room' => function ($query) use ($request) {

// If amenities is there add it to query
if($request->filled('amenities')){
$amenities = $request->amenities;
$count = count($amenities);

$query->withCount(['amenities' => function($query) use ($amenities, $count){
$query->whereIn('amenities_id', $amenities);
}])
->having('amenities_count', $count);
}

/* filter based on guest */

if($request->filled('guestsCount')){
$memberCount = $request->guestsCount + $request->childCount;
$query->Where('capacity', '>=',  $memberCount);
}else{
$query->Where('capacity', '>=',  1);
}

$query->with('roomtype')->with('floorroomcount')->with('image')->with('amenities');

$query->OrderBy('price');
$query->Where('astatus', 1)->Where('status', 0);
}]);


/* client must be active */
$buildquery->whereHas('client', function($query) {
$query->Where('status', 1);
});

/* search based on rating */
if ($request->filled('rating')) {
if($request->rating > 0){
$rating = $request->rating;
$buildquery->where('star', $rating);
}
}

/* search based on hotel */
if ($request->filled('location_id')) {
$buildquery->Where('city', $request->location_id);
}

@include('roomlist.area');

$buildquery->Where('astatus', 1)->where('status', 0); //actually its hotel

$hotels = $buildquery->simplePaginate(20);

$hotels = $this->addRates($hotels, $request->checkin_date, $request->checkout_date);
$hotels = $this->addAvailableCount($hotels, $request->checkin_date, $request->checkout_date);

$hotels = $hotels->transform(function (Hotel $hotel){

$hotel->setRelation('room', $hotel->room->sortBy('price')->flatten());

return $hotel;
});

return view('roomlist.loadmore', compact('hotels'));

пожалуйста, посмотрите эту строку @include('roomlist.area'); в этом roomlist/area.blade.php файл у меня следующий код

<?php
if($request->filled('type')){
if($request->type == "Area"){

//get the area first
$hotel = Hotel::select('area')->where('city', $request->location_id)->first();
if(isset($hotel)){
if($hotel->area != null){
$buildquery->where('area', $hotel->area);
}
}
}
}
?>

Есть ли способ, которым я могу включить этот код от лезвия или любым другим способом.

Примечание: мне нужно повторно использовать многие вещи, как это.

0

Решение

Первое, что вы можете сделать, это разбить некоторые из этих функций на области: https://laravel.com/docs/5.6/eloquent#query-scopes

Например, вы можете изменить это:

    /* search based on hotel */
if ($request->filled('location_id')) {
$buildquery->Where('city', $request->location_id);
}

В это:

if ($request->filled('location_id')) {
$buildquery->inCity($request->location_id);
}

Или это:

    /* client must be active */
$buildquery->whereHas('client', function($query) {
$query->Where('status', 1);
});

в это:

$buildquery->withActiveClient();

Это небольшое изменение, но оно позволяет вам использовать inCity в других местах без переписывания, а для других областей это может быть больше кода, который вы можете извлечь.

Вы также можете создать класс Transformer, чтобы изменить это:

    $hotels = $hotels->transform(function (Hotel $hotel){

$hotel->setRelation('room', $hotel->room->sortBy('price')->flatten());

return $hotel;
});

К этому:

    $hotels = (new HotelRoomTransformer())->transform($hotels);

Этот тип извлечения кода может сделать этот файл намного более читабельным, и, таким образом, если вам нужно будет повторно использовать его части, вы получите их в отдельных, повторно используемых файлах.

Наконец, этот тип функциональности может быть извлечен в репозиторий, если вы хотите полностью удалить Eloquent со своих контроллеров. Вот краткое руководство по шаблону репозитория: https://medium.com/@connorleech/use-the-repository-design-pattern-in-a-laravel-application-13f0b46a3dce

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]