Участники мероприятия Laravel красноречивые против коллекций

#laravel #collections #eloquent

#laravel #Коллекции #красноречивый

Вопрос:

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

Схема

         Schema::create('events', function (Blueprint $table) {
            $table->id();
            $table->datetime('occurs_at');
            $table->smallInteger('spaces_available')->unsigned()->default('8');
        });
  

Приложение Событие

     public function attendees ()
    {
        return $this->hasMany(User::class);
    }
  

Запрос:

                 AppEvent::withCount('attendees')
                    ->get()
                    ->filter(function ($event) {
                        return ($event->spaces_available - $event->attendees_count) > 0;
                    });
  

Просто интересно, как бит filter () в коллекции может быть выполнен в запросе Eloquent вместо этого?

Ответ №1:

Вы можете сделать это вручную, используя whereRaw() метод в Eloquent:

 $availableEvents = Event::query()
    ->whereRaw('spaces_available - (select count(*) from users where event_id = events.id) > 0')
    ->get();
  

И, конечно, вы могли бы добавить область для этого в свою Event модель:

 class Event extends Model
{
    public function attendees()
    {
        return $this->hasMany(User::class);
    }

    public function scopeStillAvailable($query)
    {
        $query->whereRaw('spaces_available - (select count(*) from users where event_id = events.id) > 0');
    }
}
  

И теперь вы можете сделать это:

 $availableEvents = Event::stillAvailable()->get();