Laravel自增字段时禁用自动更新"updated_at"

3
我正在递增表格中的一些总字段。
$model->total_comments += 1;
$model->save();

然而,这会触发updated_at日期的更新。我希望在这些情况下禁用它。我知道我可以手动禁用时间戳字段的自动更新。但是希望有一种简单的方法来实现。

编辑:

添加我的代码示例。请注意,此模型上没有设置观察者。

namespace App\Models;

class Language extends \Illuminate\Database\Eloquent\Model
{

}

$router->get('/test', function () {
    $model = \App\Models\Language::find(1);

    $model->words_total = $model->words_total + 1;
    $model->save(['timestamps' => false]);

    return 'boo';
});

你在更新时不需要时间戳吗? - aldrin27
每当我发现自己“需要”禁用更新时间戳时,我得出结论是我的模型中有一个不应该存在的属性。我不会将total_comments定义为模型的属性,而是会计算评论数量。尽量保持数据库规范化。 - Thomas Jensen
5个回答

5

注意,当前框架存在一个bug,阻止了第一个解决方案的正常运行。如果修复了,我会及时更新此帖。Github问题


您可以向save()传递选项数组并为该保存禁用时间戳:

$model->save(['timestamps' => false]);

当然,你也可以在模型上设置该属性,但这将要求你在可能继续使用同一模型实例时将其设置回true

$model->timestamps = false;
$model->save();
$model->timestamps = true;

不确定 ->save(['timestamps' => false]) 是怎么回事。当我执行 ->getDirty() 时,它并没有显示 updated_at。我甚至可以将 Eloquent\Model 中的 updateTimestamps 方法注释掉。同时禁用了所有观察者。但是它仍然会更新 updated_at 字段。我从缓存中获取它,但不知道这是否有影响。它还继承自一个父模型,该父模型又继承自 BaseModel。由于 updateTimestamps 方法已经被完全注释掉(并且运行了 dump-autoload),我找不到这个更新操作的源头。 - Rob
奇怪。你的数据库是否真的会使用新的时间戳更新字段?(在mysql中使用ON UPDATE CURRENT_TIMESTAMP)为了确定,记录DB查询并查看Eloquent实际执行了什么。 - lukasgeiter
我有一个调试栏,它在更新查询中包含 updated_at。我已经检查了表格,没有自动更新。当我通过手动启用/禁用 $model->timestamps 的第二种方法执行时,它不会触发。我猜这意味着在这种情况下它不是来自 MySQL 端。 - Rob
从代码框架来看,我并没有发现选项无法工作的原因... 在Github中查看 - lukasgeiter
1
虽然不是Eloquent专家,但可能是Builder中的一些错误。如果您查看Illuminate\Database\Eloquent\Model@performUpdate方法,您会发现有一行代码$this->setKeysForSaveQuery($query)->update($dirty);,其中setKeysForSaveQuery接收一个Builder对象。更新操作是从该Builder中调用的,它似乎仅检查模型的timestamps字段,而不再检查timestamps参数。在Illuminate\Database\Eloquent\Builder@update中,有一行代码return $this->query->update($this->addUpdatedAtColumn($values));,如果您跟随这个过程,将设置更新字段。 - Rob
那绝对是个bug!我会调查并尽力修复它。我会随时通知你的。 - lukasgeiter

2

您可以在保存之前执行以下操作临时禁用时间戳。

$model->timestamps = false;

1

暂时禁用它

$model->total_comments += 1;
$model->timestamps = false;
$model->save();

0

您可以通过保存那些列的当前值(例如updated_at)来更新记录,而不更改created_atupdated_at时间戳。

Model::where('id', $id)->update(['column' => "value", 'updated_at' => DB::raw('updated_at')]);

您也可以查看此主题无需触碰时间戳进行更新(Laravel)


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接