Laravel Получить предыдущие записи по дате (оптимизация) - PullRequest
1 голос
/ 28 апреля 2020

У меня есть таблица заказов с полями:

  • имя | Строка
  • из | Дата и время
  • до | Datetime

Я выбираю некоторые из этих заказов и отображаю их в виде списка. Я также проверяю, является ли предыдущее бронирование менее 30 дней.

Я делаю это, запрашивая для каждого бронирования предыдущее бронирование:

@if ($booking->previousBooking()) // Simplified version but you get the idea

Базовый код:

public function previousBooking()
    {
        return Booking::where('from', '<', $this->from)
            ->orderByDesc('from')
            ->first();
    }

Возможно, вы уже догадались: он добавляет запрос к каждому бронированию.

Лучшим сценарием было бы попытаться загрузить «предыдущее бронирование» (с) так, чтобы оно было доступно, например:

$booking->previous_booking->from

Есть ли какой-нибудь возможный способ сделать это следующим образом?

Ограничения:

  • Я не могу запросить все заказы, закажите их по "от "а затем просто получить предыдущий индекс

1 Ответ

1 голос
/ 28 апреля 2020

Взгляните на эту статью Джонатана Рейнинка. Вы можете применить его решение, имитируя previous_booking_id в вашей модели бронирования. Затем добавьте отношение previousBooking() и выполните запрос, используя with('previousBooking'). Дайте мне знать, если вам нужна помощь по внедрению.

Обновление


Добавьте следующую область в модель бронирования:

public function previousBooking()
{
    return $this->belongsTo(Booking::class);
}

public function scopeWithPreviousBooking($query)
{
    $query->addSelect(['previous_booking_id' => Booking::select('id')
        ->whereColumn('previous_booking.from', '<', 'bookings.to')
        ->orderByDesc('from')
        ->take(1)
    ])->with('previousBooking');
}

Теперь вы можете получить все ваши бронирования с их предыдущим идентификатором бронирования, включенные с использованием этого:

$bookings = Booking::withPreviousBooking()->get();

Все заказы теперь должны иметь previous_booking_id. Мы добавляем with('previousBooking') в конец области, как будто мы запрашиваем отношение бронирования. Eloquent не заботится о том, находится ли previous_booking_id в базе данных или нет, если он доступен в модели (что мы сделали методом addSelect()).

Теперь вы сможете использовать запрошенное решение в своем представлении:

$booking->previousBooking->from

Примечание: вы можете получить доступ к предыдущему отношению Booking, только если применили область действия. Если нет, previous_booking_id недоступен, и поэтому отношение будет нулевым. Если вы всегда хотите загрузить предыдущее бронирование, рассмотрите возможность добавления его в качестве глобальной области действия . Тем не менее, я рекомендую просто применить область, где это необходимо.

...