laravel - Laravel Eloquent Accessor 奇怪的问题
问题描述
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
解决方案
发生这种情况的原因是因为您正在链接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 关系文档的查询关系部分中的“计数相关模型” :
$posts = App\Event::withCount([
'registrations as seats_booked_count' => function ($query) {
$query->where('reg_status','Confirmed')
->orWhere('reg_status','Reserved');
}
])->get();
推荐阅读
- python - 如何使用熊猫显示给定日期的季度
- swift - 如何快速解析 Apache 日志文件?
- java - Java 中的 Integer.BYTES 有什么意义?
- javascript - 如何显示来自 unicode ajax responseText 的图像?
- reactjs - 如何在 react-data-grid 中为长文本添加文本换行?
- php - Woocommerce 可下载产品作为电子邮件附件 - 403 禁止
- angular - 角度翻译提取失败
- java - 库 Armen101 / AudioRecordView:不再出现块/条
- c++ - Clang 索引未检测到 C++20 ConceptDecls
- haxe - 有什么方法可以调用函数/引用以 haxe 中另一个变量的值命名的公共变量?