Laravel 修改数据与原数据一样 导致没有执行sql

代码


$openid = "123"; // 微信openid
User::WhereIn("id",['1','2','3'])->update([
  'openid' => $openid
]);

$user = User::find(1);

// 取消所有这个openid的绑定者
User::Where(['openid' => $openid])->update([
  'openid' => null
]);

// 给1号用户绑定openid
$user->openid = $openid;
$user->save();

问题: openid = 123 有几个?
答案: 一个都没有。

原因

代码极简单

getDirty 会返回 $useroriginal(查询出来的 不允许改变) 和 attributes(手动赋值的) 不同的地方,

最后发现属性都一样,所以 $user->save() 不会执行修改。

扯淡

微信绑定 的时候发现不对劲,还以为是 laravel 或者 mysqlbug :sweat_smile:

当然

本作品采用《CC 协议》,转载必须注明作者和本文链接
专心学习不瞎搞
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 5

看着没有什么问题,这个时候封装的必要性就体现出来了。这个$user变量就不该全局存在

4年前 评论
Adachi 4年前

也就是都是null

4年前 评论
$user = User::find(1);

// 因为此处修改的涉及到 id 为 1的用户,所以$user的变量实际上在数据库已经发生了改变
User::Where(['openid' => $openid])->update([
  'openid' => null
]); 

// 此时$user变量内 open_id为123,而数据表中是null,orm修改时只会对比变量,所以不会修改
$user->openid = $openid;
$user->save();

ORM都是这样的吧,修改的时候逐一对应原数据库的值和变量的值,只修改对比出的差异字段。

要解决的话可以在上面的where条件增加限定 ->where('id', '!=' 1),此处不等于会走索引,倒是问题也不大。

另一种方法可以考虑改变ORM内的原始值

$user = User::find(1);
$user->openid = null;
$user->syncOriginal();
$user->openid = '123';
$user->save();
4年前 评论
lyxxxh (楼主) 4年前
sodasix 4年前

建议在开发环境中使用 Listerer 监听 SQL,这样查找问题会快很多,而且还可以发现查询的时候忘记使用with导致循环查询的问题。

4年前 评论

fillable 中设置 openid 了吗

4年前 评论
杰大哥 4年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
未填写
文章
89
粉丝
108
喜欢
481
收藏
724
排名:108
访问:8.8 万
私信
所有博文
社区赞助商