Проверить диапазон дат еще не забронирован в Laravel 6? - PullRequest
0 голосов
/ 04 марта 2020

Я работаю в системе онлайн-бронирования велосипедов, где клиент может забронировать велосипед для определенного диапазона времени и даты. Если другой клиент заказывает тот же велосипед для указанного диапазона времени и даты, я должен проверить, уже забронирован ли велосипед или нет. Моя таблица базы данных reservations выглядит следующим образом:

id     bike_id      start_date             end_date
 1        1      2019-05-04 14:30      2019-05-04 15:30
 1        1      2019-05-04 16:30      2019-05-04 18:30

Запрос:

Reservations::where('bike_id', $yacht)
    ->where(function ($query) use ($startTime, $endTime) {
        $query->where(function ($query) use ($startTime, $endTime) {
            $query->where('start_date', '<', $startTime)
                ->where('end_date', '>', $startTime);
        })
        ->orWhere(function ($query) use ($startTime, $endTime) {
            $query->where('start_date', '>', $endTime)
                ->where('end_date', '<', $endTime);
        });
    })
    ->count();

К сожалению, похоже, код не работает. Он не проверяет состояние должным образом. Как правильно выполнить нужную проверку с использованием заданных входов?

Ответы [ 2 ]

1 голос
/ 04 марта 2020

Ответ Намошека, основанный на вашем коде, является правильным. Лично мне трудно читать все вложенные функции. Их нельзя избежать в таком запросе, но их можно уменьшить:

$bike = Bike::findOrFail($yacht);
$conflict = $bike->reservations()
    ->whereBetween('start_date', [$startTime, $endTime])
    ->orWhereBetween('end_date' [$startTime, $endTime])
    ->orWhere(function($q) use($startTime, $endTime) {
        $q->where('start_date', '<', $startTime)->where('end_date', '>', $endTime);
    })
    ->exists();
if ($conflict) {
    abort(409);
}
// continue saving the reservation

Я предполагаю, что вы правильно установили отношения между вашими Bike и Reservation моделями, так что можете Воспользуйтесь ими, чтобы сделать код еще более читабельным. (И, возможно, вы все равно найдете этот велосипедный объект позже в коде.)

1 голос
/ 04 марта 2020

Что вы хотите проверить, так это то, находится ли начальная дата или время окончания нового бронирования в какой-либо существующей записи. Другими словами, как вы уже правильно определили, есть два случая, когда один касается времени начала нового бронирования, а другой - времени окончания. Если какой-либо (или оба) из них l ie в существующем бронировании, проверка не удалась.

use Illuminate\Database\Eloquent\Builder;

$similarBookingExists = Reservations::query()
    ->where('bike_id', $yacht)
    ->where(function (Builder $query) use ($startTime, $endTime) {
        $query->where(function (Builder $query) use ($startTime) {
            $query->where('start_date', '<=', $startTime)
                ->where('end_date', '>=', $startTime);
        })
        ->orWhere(function (Builder $query) use ($endTime) {
            $query->where('start_date', '<=', $endTime)
                ->where('end_date', '>=', $endTime);
        });
    })
    ->exists();

Короче, единственной ошибкой, которую вы сделали, были операторы сравнения < и > из второй случай для $endTime.

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