Laravel Version: 5.6.39
PHP Version: 7.1.19
Database Driver & Version: mysql 5.6.43
说明:
当我在模型访问器中链接where和orWhere来计算相关模型时,我得到错误的结果,这是我的查询。计数返回奇怪的结果,而没有按调用事件ID进行过滤,
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
答案 0 :(得分:1)
发生这种情况的原因是因为您要链接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()
是在语义上正确的事情。
尽管如此,口才可以为您解决;在口才关系文档的Querying Relations部分中向下滚动至“计算相关模型”:
$posts = App\Event::withCount([
'registrations as seats_booked_count' => function ($query) {
$query->where('reg_status','Confirmed')
->orWhere('reg_status','Reserved');
}
])->get();