更新时不触及时间戳(Laravel)

Jan*_*ele 57 php laravel eloquent laravel-4

是否可以在不触及时间戳的情况下更新用户?

我不想完全禁用时间戳..

grtz

Ant*_*iro 138

Disable it temporarily:

$user = User::find(1);
$user->timestamps = false;
$user->age = 72;
$user->save();
Run Code Online (Sandbox Code Playgroud)

You can optionally re-enable them after saving.

This is a Laravel 4 and 5 only feature and does not apply to Laravel 3.

  • 这是唯一对我有用的解决方案。我曾尝试采用更“优雅”的方式:`$something->save(['timestamps'=>false]);` 而它只是忽略了它。非常感谢大佬! (3认同)
  • 如果模型定义了“接触”,这仍然会导致关系更新。 (2认同)

小智 20

在Laravel 5.2,您可以设置的公共领域$timestamps,以false这样的:

$user->timestamps = false;
$user->name = 'new name';
$user->save();
Run Code Online (Sandbox Code Playgroud)

或者您可以将选项作为save()函数的参数传递:

$user->name = 'new name';
$user->save(['timestamps' => false]);
Run Code Online (Sandbox Code Playgroud)

为了更深入地了解它的工作原理,您可以\Illuminate\Database\Eloquent\Model在方法中查看该类performUpdate(Builder $query, array $options = []):

protected function performUpdate(Builder $query, array $options = [])
    // [...]

    // First we need to create a fresh query instance and touch the creation and
    // update timestamp on the model which are maintained by us for developer
    // convenience. Then we will just continue saving the model instances.
    if ($this->timestamps && Arr::get($options, 'timestamps', true)) {
        $this->updateTimestamps();
    }

    // [...]
Run Code Online (Sandbox Code Playgroud)

仅当公共属性timestamps等于trueArr::get($options, 'timestamps', true)返回时才更新时间戳字段true(如果$options数组不包含键,则默认情况下会更新timestamps).

只要其中一个返回false,timestamps字段就不会更新.

  • 请注意,此功能在Laravel 5.1和5.2中已被破坏,因此已从Laravel 5.3中删除*.请参阅:https://github.com/laravel/framework/issues/10028 (15认同)

azn*_*t81 15

加入Antonio Carlos Ribeiro的回答

如果您的代码需要在50%以上的时间内取消激活时间戳 - 也许您应该禁用自动更新并手动访问它.

在扩展雄辩模型时,您可以通过放置来禁用时间戳

UPDATE

public $timestamps = false;

在你的模型里面.


小智 14

上面的示例很酷,但仅适用于单个对象(每次只有一行).

如果要更新整个集合,这是如何临时禁用时间戳的简便方法.

class Order extends Model
{

 ....

    public function scopeWithoutTimestamps()
    {
        $this->timestamps = false;
        return $this;
    }

}
Run Code Online (Sandbox Code Playgroud)

现在你可以简单地调用这样的东西:

Order::withoutTimestamps()->leftJoin('customer_products','customer_products.order_id','=','orders.order_id')->update(array('orders.customer_product_id' => \DB::raw('customer_products.id')));
Run Code Online (Sandbox Code Playgroud)

  • 它的订单::**w**ithoutTimestamps(),请修复 (3认同)

hil*_*ius 7

对于尝试执行Model::update()呼叫的Laravel 5.x用户,要使其正常工作,您可以使用

Model::where('example', $data)
     ->update([
       'firstValue' => $newValue,
       'updatedAt' => \DB::raw('updatedAt')
     ]);
Run Code Online (Sandbox Code Playgroud)

由于Model :: update函数不再使用第二个参数.ref:laravel 5.0 api

测试并使用5.2版.


Luc*_* C. 6

如果您需要更新单个模型查询:

$product->timestamps = false;
$product->save();
Run Code Online (Sandbox Code Playgroud)

要么

$product->save(['timestamps' => false]);
Run Code Online (Sandbox Code Playgroud)

如果您需要更新多个模型查询,请使用

DB::table('products')->...->update(...)
Run Code Online (Sandbox Code Playgroud)

代替

Product::...->update(...)
Run Code Online (Sandbox Code Playgroud)


Chr*_*ius 6

Laravel 9 及以上版本

直接取自文档

如果您想在不修改模型时间戳的情况下执行模型操作updated_at,您可以在给定方法的闭包内对模型进行操作withoutTimestamps

Model::withoutTimestamps(fn () => $post->increment(['reads']));
Run Code Online (Sandbox Code Playgroud)

所以在OP的例子中,代码将是这样的:

User::withoutTimestamps(function () {
    $user = User::find(1);
    $user->name = 'John';
    $user->save();
});
Run Code Online (Sandbox Code Playgroud)


Zan*_*per 5

我遇到了需要进行涉及连接的批量更新的情况,因此updated_at导致重复列冲突。我在不需要范围的情况下使用此代码修复了它:

$query->where(function (\Illuminate\Database\Eloquent\Builder $query) {
    $query->getModel()->timestamps = false;
})
Run Code Online (Sandbox Code Playgroud)