Laravel красноречивый запрос с использованием локальной области видимости с условным оператором и аргументами - PullRequest
0 голосов
/ 19 июня 2020

Я написал следующую функцию в своей модели автомобиля, которая выполняет следующие действия:

  1. Получает соответствующие бронирования на основе двух дат (получение / высадка)
  2. Проверяет, количество этих резервирований равно или превышает количество автомобиля
  3. Наконец, возвращает логическое значение в зависимости от вывода
   /**
    * Custom Functions
    */

   public function isAvailableFor($from, $to) {
       $reservationsCount = $this->reservations->where('pickup_date', '>=', $from)->where('dropoff_date', '<=', $to)->count();
       if($reservationsCount >= $this->quantity) {
           return false;
       }
       return true;
   }

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

Например, у меня есть следующая область видимости, которую я использую, просто набрав Car::active()->get();

    /**
     * Scopes
     */
    public function scopeActive($query)
    {
        return $query->where('status', 'active');
    }

. Основная проблема заключается в функции count(), которая не позволяет мне реализовать мою функцию в режиме видимости или по крайней мере, я не настолько опытен, чтобы находить решение. Заранее спасибо.

Обновление

Как правильно указал OsDev, поскольку моя функция возвращает логическое значение, это не может быть реализовано непосредственно в функции области видимости. В качестве альтернативы я могу сделать это в своей функции области видимости, но я думаю, что это в значительной степени излишний:

    public function scopeAvailable($query, $from, $to) {
        $excludedId = array();
        $cars = Car::whereHas('reservations')->get();
        foreach($cars as $car) {
            if(!$car->isAvailableFor($from, $to)) {
                array_push($excludedId, $car->id);
            }
        }
        return $query->whereNotIn('id', $excludedId);
    }

1 Ответ

0 голосов
/ 19 июня 2020

Вы должны вернуть $query вместо результата подсчета, потому что таким образом вы не разорвете цепочку Query Builder

Вы не можете комбинировать области действия и функции модели, поскольку области должны возвращать $query объект строителя, и в этом примере ваша функция возвращает логическое значение.

Вы можете сделать что-то вроде этого

  /**
     * Scopes
     */
    public function scopeIsAvailableFor($query,$from,$to)
    {
        return $query->where('pickup_date', '>=', $from)->where('dropoff_date', '<=', $to);
    }

Затем вы можете связать его и вызвать счетчик, если хотите

$count = Car::active()->isAvailableFor('2020-05-03','2020-05-06')->count();

Возможно, вы сможете обернуть свой новый прицел в метод своей модели

public function isAvailableFor($from, $to) {

    $reservationsCount = $this->reservations->isAvailableFor($from,$to)->count();

    return !$reservationsCount >= $this->quantity;

   }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...