在不触动时间戳的情况下进行更新(Laravel)
问题的原因是在Laravel中,如果要更新模型但不更新时间戳,需要手动禁用时间戳功能。而问题的解决方法是在保存模型之前,将时间戳功能禁用,然后再重新启用。具体的解决方法是在保存模型之前,将时间戳属性设置为false,然后进行保存操作。以下是解决方法的示例代码:
$user = User::find(1); $user->timestamps = false; $user->age = 72; $user->save();
需要注意的是,这个解决方法只适用于Laravel 4和Laravel 5,不适用于Laravel 3。在Laravel 3中,时间戳属性是静态的,无法在运行时进行更改。如果在Laravel 3中想要禁用时间戳,可以查看以下代码:
https://github.com/laravel/laravel/blob/3.0/laravel/database/eloquent/model.php#L71
有用户提到在尝试使用更"优雅"的方式$something->save(['timestamps' => false]);
时,并没有起作用。而禁用时间戳的唯一解决方法是在保存模型之前禁用时间戳功能。此外,还有用户提到如果模型定义了"touches"属性,即使禁用了时间戳功能,关联模型仍然会被更新。
在Laravel中,如果我们想要更新整个集合而不触碰时间戳,可以使用以下方法:
首先,我们需要在Order模型中添加一个scopeWithoutTimestamps()方法,代码如下:
class Order extends Model { public function scopeWithoutTimestamps() { $this->timestamps = false; return $this; } }
这个方法的作用是将timestamps属性设置为false,从而临时禁用时间戳。
接下来,我们可以简单地调用这个方法来更新整个集合,示例代码如下:
Order::withoutTimestamps() ->leftJoin('customer_products', 'customer_products.order_id', '=', 'orders.order_id') ->update(['orders.customer_product_id' => \DB::raw('customer_products.id')]);
在上面的代码中,我们使用了leftJoin()来进行表连接操作,并且使用update()方法来更新数据。值得注意的是,在调用withoutTimestamps()方法时要注意拼写,正确的调用方式是Order::withoutTimestamps()。
另外,如果你使用的是Laravel 9版本,可以使用以下代码来定义scopeWithoutTimestamps()方法:
public function scopeWithoutTimestamps($query) { $this->timestamps = false; return $query; }
以上就是在Laravel中更新数据时不触碰时间戳的方法。通过添加一个scopeWithoutTimestamps()方法,并将timestamps属性设置为false,我们可以临时禁用时间戳,从而实现对整个集合的更新操作。
Laravel中的"Update without touching timestamps (Laravel)"问题是出现的原因和解决方法。在Laravel 5.2中,可以通过设置模型的公共字段"$timestamps"为false来实现更新操作而不触碰时间戳。具体的方法有两种:
第一种方法是直接将"$timestamps"属性设置为false,然后更新模型的其他字段,最后保存模型:
$user->timestamps = false; $user->name = 'new name'; $user->save();
第二种方法是将选项作为参数传递给"save()"方法:
$user->name = 'new name'; $user->save(['timestamps' => false]);
为了更深入地了解其工作原理,可以查看"\Illuminate\Database\Eloquent\Model"类中的"performUpdate(Builder $query, array $options = [])"方法。在该方法中,如果"$timestamps"属性为true,并且$option数组中没有包含"timestamps"键或者"timestamps"键对应的值为true(默认情况下是true),则会更新时间戳字段:
protected function performUpdate(Builder $query, array $options = []) // [...] // 首先,我们需要创建一个新的查询实例并触摸我们开发人员方便的模型上的创建和更新时间戳。 // 然后我们只需继续保存模型实例。 if ($this->timestamps && Arr::get($options, 'timestamps', true)) { $this->updateTimestamps(); } // [...]
只要其中一个条件返回false,时间戳字段就不会被更新。
需要注意的是,在Laravel 5.1和5.2中,这个功能是有问题的,因此在Laravel 5.3中已经被移除。在Laravel 8中,这个功能也不起作用。
在Laravel 8中,可以尝试在调用"update()"方法之前将模型的"$timestamps"属性设置为false,但这个方法尚未经过测试。
要在Laravel中进行更新操作而不触碰时间戳字段,可以通过设置模型的"$timestamps"属性为false,或者将选项传递给"save()"方法来实现。然而,需要注意的是,在Laravel 5.1和5.2中存在问题,因此在Laravel 5.3中已经移除了该功能。在Laravel 8中,这个功能也不起作用。