У меня есть простая функция бронирования, реализованная моделью Shifts
(для доступности) и Bookings
(для зарезервированных смен).
A Shift
имеет определенный уровень вместимости, так чтоЯ считаю его Открыт , когда его вместимость еще не забронирована, и Закрыт , если его вместимость полностью забронирована.
Относительно отношений, у смены много заказов., поскольку каждое резервирование считается за 1 занятый ресурс.
Мне нужно захватить все Открытые смены , используя метод Eloquent scope
, который я считаюсамый естественный (Laravelish) способ сделать это.
Другими словами, я хочу перечислить смены с открытыми позициями.т. е. сдвиги с подтвержденными заказами
Тестовый сценарий
Чтобы показать пример того, как выглядит моя фактическая БД, я создал эту БД SQL Fiddle , которая выполняет следующий RAW-запрос, который яЯ хотел бы перевести в форму метода области видимости.
SELECT shifts.*, COUNT(bookings.id) as num_of_bookings
FROM shifts
LEFT JOIN bookings on bookings.shift_id = shifts.id
GROUP BY shifts.id
HAVING shifts.quantity > num_of_bookings
Я понимаю, что мне нужно получить что-то в форме:
public function scopeOpen ($query) {
return $query->whereDoesntHave('bookings', function ($q) {
// $q->.....
})
}
Но ячестно пытаюсь построить правильное утверждение.
Любые идеи по этому поводу приветствуются.
Схема миграции баз данных
Schema::create('shifts', function (Blueprint $table) {
$table->string('id');
$table->primary('id');
$table->unsignedInteger('client_id')->index();
$table->foreign('client_id')->references('id')->on('clients');
$table->unsignedInteger('facility_id')->index();
$table->foreign('facility_id')->references('id')->on('facilities');
$table->string('qualification');
$table->tinyInteger('quantity')->unsigned()->default(1);
$table->unsignedInteger('rate');
$table->dateTime('start');
$table->dateTime('end');
$table->smallInteger('break')->unsigned()->nullable()->comment('in minutes');
$table->text('description')->nullable();
$table->timestamps();
$table->softDeletes();
});
Schema::create('bookings', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('nurse_id')->index();
$table->foreign('nurse_id')->references('id')->on('nurses');
$table->string('shift_id')->index();
$table->foreign('shift_id')->references('id')->on('shifts');
$table->string('creator_type')->nullable();
$table->integer('creator_id')->nullable();
$table->dateTime('confirmed_at')->nullable();
$table->string('confirmer_type')->nullable();
$table->integer('confirmer_id')->nullable();
$table->dateTime('canceled_at')->nullable();
$table->string('canceler_type')->nullable();
$table->integer('canceler_id')->nullable();
$table->timestamps();
$table->softDeletes();
});
Я хочу перечислить доступные смены,т.е. сдвигается с меньшим количеством заказов, которые сдвигаются -> количество.(другие ограничения не важны сейчас).
Редактировать
Прямо сейчас я использую следующую локальную область.но если вы можете сделать это чище, то есть меньше необработанных запросов, я буду рад.
public function scopeOpen($query)
{
return $query->whereRaw("
quantity > ( select count(*)
from bookings
where shifts.id = bookings.shift_id
and confirmed_at is not null
and canceled_at is null
)
");
}