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 协议》,转载必须注明作者和本文链接
Good Good Study , Day Day Up!!
Jourdon
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 4

就算禁止更新,也可以在Model里面设置$dates吧,这样updated_at还是日期对象不是字符串

4年前 评论
Jourdon

@zdg1992 这里说的禁止更新,只是临时禁止而已,和MODEL里的设置无关

4年前 评论
lufeijun1234

临时禁止更新的话,用 DB 是不是可以

4年前 评论
Jourdon

@lufeijun1234 时间的自动更新只针对ORM, DB 没有自动更新这一说。

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!