ORM 禁止 update_at 的自动更新后遇到的坑及解决办法!
这里说的是禁止更新只是方法里的临时禁止,不涉及到 MODEL 里的设置
其实这个问题本不需要再另外发个贴子出来的,社区包括网上已经有答案了,可惜。我还是遇到了一个大坑。
先看代码:
$user = \App\Models\User::find(1);
$user->sex = 1;
$user->timestamps = false;
$user->save();
return [
'id' => $user->id,
'name' => $user->name,
'sex' => $user->sex,
'created_at' => $user->created_at->toDateTimeString(),
'updated_at' => $user->updated_at->toDateTimeString(),
];
很简单的一段代码。更新性别并禁止更新timestamps
后保存实例并返回,这里报了个错出来:
Call to a member function toDateTimeString() on string
可以定位到出问题的地方在返回实例的地方,
'created_at' => $user->created_at->toDateTimeString(),
我们来复现这个问题
$user = \App\Models\User::find(1);
$user->sex = 1;
$user->save();
dump($user->created_at);
dump($user->updated_at);
//打印出来的结果
// Carbon @1557115752 {#1142 ▼ `date: 2019-05-06 12:09:12.0 Asia/Shanghai (+08:00)` }
//Carbon @1575627187 {#1157 ▼ `date: 2019-12-06 18:13:07.0 Asia/Shanghai (+08:00)` }
禁止更新timestamps
后再看。
$user = \App\Models\User::find(1);
$user->sex = 1;
$user->timestamps = false;
$user->save();
dump($user->created_at);
dump($user->updated_at);
//打印出来的结果
//"2019-05-06 12:09:12"
//"2019-12-06 18:13:07"
正常访问更新后,时间还是Carbon
对象,但是禁用timestamps
后时间变成了字符串,本来这不是什么大问题,除非你在接下来逻辑里会对时间进行处理。比如$user->created_at->toDateTimeString(),
,字符串当然不会有toDateTimeString
这个方法。所以这里可以使用 ORM 的fresh
方法为重新加载模型。
更改后的代码
$user = \App\Models\User::find(1);
$user->sex = 1;
$user->timestamps = false;
$user->save();
$updatedUser =$user->fresh();
return [
'id' => $updatedUser->id,
'name' => $updatedUser->name,
'sex' => $updatedUser->sex,
'created_at' => $updatedUser->created_at->toDateTimeString(),
'updated_at' => $updatedUser->updated_at->toDateTimeString(),
];
源码上我还没有找到是在哪里引起的这个问题,也希望大佬们来帮忙看看
OVER!
本作品采用《CC 协议》,转载必须注明作者和本文链接
就算禁止更新,也可以在Model里面设置$dates吧,这样updated_at还是日期对象不是字符串
@zdg1992 这里说的禁止更新,只是临时禁止而已,和
MODEL
里的设置无关临时禁止更新的话,用 DB 是不是可以
@lufeijun1234 时间的自动更新只针对
ORM
,DB
没有自动更新这一说。