【问题标题】:Why Laravel save method changes updated_at column and other timestamp columns?为什么 Laravel 保存方法会更改 updated_at 列和其他时间戳列?
【发布时间】:2020-05-15 10:49:10
【问题描述】:

我在数据库中创建了这样的表。

Schema::create('packages', function (Blueprint $table) {
    $table->increments('id');
    $table->unsignedInteger('count');
    $table->timestamp('expire_date');
    $table->timestamps();
});

现在假设我们在数据库中有以下记录:

+----+-------+---------------------+---------------------+---------------------+
| id | count | expire_date         | created_at          | updated_at          |
+----+-------+---------------------+---------------------+---------------------+
|  1 |   120 | 2018-01-31 19:22:45 | 2018-01-29 17:12:01 | 2018-01-29 19:22:45 |
|  4 |   140 | 2018-02-14 19:05:01 | 2018-01-29 17:20:16 | 2018-01-29 19:05:01 |
| 27 |    10 | 2018-02-17 19:01:10 | 2018-01-29 19:05:01 | 2018-01-29 19:05:01 |
+----+-------+---------------------+---------------------+---------------------+

当我尝试使用 laravel eloquent 编辑记录时:

$package = \App\Package::find(1);
$package->count = 100;
$package->save();

save 方法将 expire_date 和 updated_at 列都更改为当前时间!

+----+-------+---------------------+---------------------+---------------------+
| id | count | expire_date         | created_at          | updated_at          |
+----+-------+---------------------+---------------------+---------------------+
|  1 |   100 | 2018-01-29 19:32:24 | 2018-01-29 17:12:01 | 2018-01-29 19:32:24 |
|  4 |   140 | 2018-02-14 19:05:01 | 2018-01-29 17:20:16 | 2018-01-29 19:05:01 |
| 27 |    10 | 2018-02-17 19:01:10 | 2018-01-29 19:05:01 | 2018-01-29 19:05:01 |
+----+-------+---------------------+---------------------+---------------------+

为什么 expire_date 的值会发生变化,甚至没有触摸它?!!!

【问题讨论】:

  • @TimLewis 我在问为什么 expire_date 会发生变化。
  • 也许你正在使用另一个包,而那个包改变了字段
  • @MahdiYounesi 不,我找到了原因。这是因为 mysql 自动初始化和更新 TIMESTAMP 和 DATETIME dev.mysql.com/doc/refman/5.7/en/timestamp-initialization.html
  • 你应该使用 Datetime 作为那个 'expire_at' 列。

标签: laravel laravel-5.5


【解决方案1】:

看看你的表 DDL,它会是

expire_date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
created_at timestamp NULL DEFAULT NULL,
updated_at timestamp NULL DEFAULT NULL,

expire_date 默认值为当前时间戳。
您需要做的就是将ON UPDATE CURRENT_TIMESTAMP 更改为null。

ALTER TABLE table ALTER COLUMN expire_date DEFAULT NULL

或在您创建之前:

https://github.com/laravel/framework/blob/be09eac00a2f750dc2d2209078cf61ae2eee85a1/src/Illuminate/Database/Schema/Grammars/MySqlGrammar.php#L647

https://github.com/laravel/framework/blob/d598a6630208b054376527e41848c106f4297b2b/src/Illuminate/Database/Schema/ColumnDefinition.php#L26

$table->timestamp('expire_date')->useCurrent(false);

【讨论】:

    【解决方案2】:

    来自the docs

    save 方法也可用于更新数据库中已存在的模型。要更新模型,您应该检索它,设置您希望更新的任何属性,然后调用 save 方法。同样,updated_at 时间戳会自动更新,因此无需手动设置其值

    因此,Eloquent 仅更新 updated_at。如果expire_date 也更新了,这意味着应用程序中使用了 Eloquent 事件或正在发生类似的事情(例如 DB updates 它)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-01-22
      • 2017-07-07
      • 2013-02-05
      • 2017-03-06
      • 2018-04-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多