返回

在 Eloquent 中如何轻松实现有选择地更新时间戳?

php

如何在 Eloquent 中有选择地更新时间戳

引言

对于使用 Laravel Eloquent ORM 的开发者而言,管理模型的时间戳是一个常见问题。我们需要在某些情况下更新时间戳,但在其他情况下又不需要。手动处理此过程可能很繁琐且容易出错。

解决方案

为了解决此问题,我们可以扩展 Eloquent 的 fill() 方法,以有选择地更新时间戳。

扩展 Eloquent 的 Fill 方法

public function fill(array $data)
{
    $needTimestampTouch = $this->getNeedTimestampTouch($data);
    if (!empty($needTimestampTouch)) {
        $this->timestamps = false;
    }

    parent::fill($data);

    $this->timestamps = true;

    return $this;
}

确定需要更新时间戳的属性

接下来,我们需要创建 getNeedTimestampTouch() 方法来确定哪些属性的更改需要更新时间戳。

protected function getNeedTimestampTouch(array $data)
{
    $leaveUntouched = ['active' => true];
    $changed = array_diff_assoc($data, $this->toArray());
    return array_diff_key($changed, $leaveUntouched);
}

在这个示例中,我们将 active 字段列入白名单,表明其更改不会触发时间戳更新。

示例用法

现在,我们可以使用更新后的 fill() 方法在我们的模型中更新数据,而不必担心手动处理时间戳。

$instance = $model::find($data["id"]);
$instance->fill($data);
$instance->save();

结论

通过扩展 Eloquent 的 fill() 方法,我们创建了一个优雅且可维护的解决方案来有选择地更新模型的时间戳。它简化了代码,并消除了手动处理时间戳的需要,从而提高了开发效率。

常见问题解答

1. 为什么我们需要有选择地更新时间戳?

对于只对某些属性进行微小更改的情况,避免更新时间戳可以优化性能。

2. 如何自定义 getNeedTimestampTouch() 方法?

根据业务需求,可以自定义 getNeedTimestampTouch() 方法来确定需要更新时间戳的属性。

3. 这种方法是否适用于所有 Eloquent 模型?

是的,这种方法适用于扩展了 BaseModel 的所有 Eloquent 模型。

4. 这是否会影响模型的创建和更新事件?

不会,此方法只影响通过 fill() 方法更新模型。创建和更新事件将继续正常触发。

5. 如何在不扩展 BaseModel 的情况下实现此功能?

可以使用中间件或观察器来在保存模型之前禁用时间戳。