framework icon indicating copy to clipboard operation
framework copied to clipboard

[ BUG ] 模型层更新时 无法关闭全局范围查询

Open 153264 opened this issue 3 years ago • 7 comments

示例在这 https://github.com/153264/bug_report 数据已经查询出来了 但是更新的时候又带上了查询范围scope

1647004950(1)

153264 avatar Mar 11 '22 13:03 153264

写入之前调用withoutGlobalScope(['status'])试试, 比如:

$a->withoutGlobalScope(['status'])->save(['user_status'=>1]);

augushong avatar Mar 11 '22 13:03 augushong

写入之前调用withoutGlobalScope(['status'])试试, 比如:

$a->withoutGlobalScope(['status'])->save(['user_status'=>1]);

感谢 但是明明数据都已经查询出来了 更新时还要再设置一次 这是让我没想到的

$a = User::withoutGlobalScope(['status'])->find(1);
$a->withoutGlobalScope(['status'])->save([
      'user_status'=>1,
      'user_id' => $a->user_id
 ]);

153264 avatar Mar 11 '22 21:03 153264

我突然发现 用上面的写法没触发模型层的事件 onBeforeUpdate 1647038252(1)

153264 avatar Mar 11 '22 22:03 153264

只有查询后save保存的用法可以触发数据库事件, 其余的都不是模型的标准用法.

augushong avatar Mar 12 '22 02:03 augushong

查询范围影响的是本次数据库操作,所以查询是查询,更新是更新. 如果你希望有一个全局的关闭,可以自己设法实现, 比如设置一个静态属性,在scope的查询里先判断这个属性是否需要查询,比如:

 public static $enableStatusScope = true;

 public function scopeStatus($query)
    {
      if(static::$eneableStatusScope){
        $query->where('status',1);
        }
    }

这样你可以通过下面的方法全局关闭:

User::$enableStatusScope  = false;
// 以后的查询就不会启用全局范围了,
// 实际上全局范围仍然被调用,只不过内部的函数做了判断,没有修改query而已.

这种做法很糟糕,不应该这样做.

全局范围,应该与单条数据的业务逻辑无关,应该用于sass的产品逻辑,比如,产品属于仓库,在产品设计中,页面总是进入仓库,才会查询产品,这时可以给产品设置一个全局的范围查询,即指定的仓库id.其他的比如团队,组织,公司等场景,都可以用. 这种情况下不会出现临时关闭全局查询的情况.

augushong avatar Mar 12 '22 03:03 augushong

你是怎么判断出来模型事件不能用的,update_time字段会自动更新吧.你换个别的字段修改试试.

augushong avatar Mar 12 '22 03:03 augushong

你是怎么判断出来模型事件不能用的,update_time字段会自动更新吧.你换个别的字段修改试试.

update_time是 onBeforeUpdate 事件加的 就是用来模拟流程 实际有业务有其他逻辑在事件里面

153264 avatar Mar 12 '22 07:03 153264