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 协议》,转载必须注明作者和本文链接
专心学习不瞎搞
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 5

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

3年前 评论
Adachi 3年前

也就是都是null

3年前 评论
$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();
3年前 评论
lyxxxh (楼主) 3年前
sodasix 3年前

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

3年前 评论

fillable 中设置 openid 了吗

3年前 评论
杰大哥 3年前

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