【问题标题】:Laravel Eloquent Accessor Strange IssueLaravel Eloquent Accessor 奇怪的问题
【发布时间】:2019-07-27 18:56:46
【问题描述】:
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 

【问题讨论】:

    标签: laravel eloquent


    【解决方案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() 在语义上是正确的做法。

    不过,Eloquent 可以为您处理这个问题;向下滚动到 Eloquent 关系文档的 Querying Relations 部分中的“计数相关模型”:

    $posts = App\Event::withCount([
        'registrations as seats_booked_count' => function ($query) {
                $query->where('reg_status','Confirmed')
                    ->orWhere('reg_status','Reserved');
        }
    ])->get();
    

    【讨论】:

    • 你是对的,如果我明确地对 where 语句进行分组,查询工作正常或使用 whereIn 也可以解决问题,就我而言,框架必须通过将我的语句单独分组或 at- 来处理这个问题至少在文件中提到这一点作为警告,不是吗? .我在 github 上打开了一个关于此的问题。 github.com/laravel/framework/issues/…
    • 框架应该如何确定您是否/如何对它们进行分组? where()->orWhere() 不会在括号中放入任何内容,但您希望 where()->where()->orWhere() 将它们放入括号中?我在这里看不到一个简单的解决方案。如果这个想法是“检查有多少方法链接在哪里” - 正如您在上面的示例中看到的那样,开发人员没有编写第一个 where()
    • 看看我的问题,我在这两种情况下都用查询转储更新它,当我自己分组而不是分组时,
    猜你喜欢
    • 2012-10-24
    • 2016-01-31
    • 2018-02-20
    • 2013-12-24
    • 2020-06-27
    • 2020-01-29
    • 2020-05-13
    • 2016-01-14
    • 1970-01-01
    相关资源
    最近更新 更多