Laravel Eloquent Accessor Странная проблема - PullRequest
0 голосов
/ 06 марта 2019
Laravel Version: 5.6.39
PHP Version: 7.1.19
Database Driver & Version: mysql 5.6.43

Описание:

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

class Event extends Model
{
    protected $table = 'events';
    public function registrations()
    {
        return $this->hasMany('App\Components\Event\Models\Registration','event_id','id');
    }

    public function getSeatsBookedAttribute()
    {
        return $this->registrations()          
            ->where('reg_status','=','Confirmed')
            ->orWhere('reg_status','=','Reserved')
            ->count();
    }
}

Шаги для воспроизведения:

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

class Event extends Model
{
    public function getSeatsBookedAttribute()
    {
        return $this->registrations()          
             ->whereIn('reg_status', ['Confirmed', 'Reserved'])
            ->count();
    }

}


class Event extends Model
{
    public function getSeatsBookedAttribute()
    {
        return $this->registrations()          
          ->where(function($query){
                $query->where('reg_status','Confirmed')
                    ->orWhere('reg_status','Reserved');
           })
            ->count();
    }

}

, а вот дамп запроса,

здесьзапрос, когда я не могу явно сгруппировать его.

"select count(*) as aggregate from events_registration where (events_registration.event_id = ? and events_registration.event_id is not null and reg_status = ? or reg_status = ?) and events_registration.deleted_at is null "

и вот запрос, когда я сгруппировал его явно,

select count(*) as aggregate from events_registration where events_registration.event_id = ? and events_registration.event_id is not null and (reg_status = ? or reg_status = ?) and events_registration.deleted_at is null 

1 Ответ

1 голос
/ 06 марта 2019

Причина, по которой это происходит, в том, что вы соединяете where() и orWhere().То, что вы не видите за кадром, это where event_id = :event_id применение к вашему запросу.В итоге вы получите запрос, который выглядит примерно так:

select * from registrations where event_id = :event_id and reg_status = 'Confirmed' or reg_status = 'Reserved'

В обычном SQL вы бы хотели поместить последние 2 условия в скобки.Для Eloquent вам нужно сделать что-то вроде этого:

return $this->registrations()->where(function ($query) {
   $query->where('reg_status', 'Confirmed')
      ->orWhere('reg_status', 'Reserved');
});

Вы можете связать метод toSql() в этих цепочках, чтобы увидеть разницу.Обратите внимание, что в этом случае, я считаю, whereIn() является семантически правильной вещью.

Eloquent может справиться с этим за вас;прокрутите вниз до «Подсчета связанных моделей» в Запрашиваемых отношениях части документов Eloquent Relationships:

$posts = App\Event::withCount([
    'registrations as seats_booked_count' => function ($query) {
            $query->where('reg_status','Confirmed')
                ->orWhere('reg_status','Reserved');
    }
])->get();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...