如何在创建或删除关系时自动更新 parent 模型的时间戳?

How to automatically update the timespamps of parent model when a relationship is being created or removed?

在 Laravel 中,一个与另一个模型具有 belongs to 关系的模型在其 table 上也有一个指向 id<parent>_id 字段parent。当该模型与另一个模型相关联时,updated_at 时间戳自然会更新,因为 <parent>_id 字段的值会发生变化。

虽然 parent 模型具有 has many 关系,但是当它成为或停止与 child 模型相关时,没有任何字段会发生变化,因此它的 updated_at 时间戳没有改变。

我想要的是 parent 和 child 模型在每次创建或删除两者之间的关系时自动更新它们的 updated_at 时间戳。实现这一目标的正确方法是什么?

我已经研究过 touches 属性,它会导致 parent 的时间戳在 child 被修改时自动更新。但这仅在创建新关系时有效,而不是在删除旧关系时有效。而且,这将在任何字段发生变化时更新 parent 的时间戳,而不仅仅是 <parent>_id 的时间戳,这是我实际上不想要的。

您可以使用 Eloquent 提供的 touch 方法来更新 parent 的 updated_at 时间戳。

$parent->touch(); //will update updated_at 

如果我没有误解的话,除了在需要时调用此内联或在 child(例如创建和删除或创建和删除)用于触摸 parent 的时间戳。

摘自 Laravel Docs.

触摸父时间戳

当模型 belongsTobelongsToMany 另一个模型时,例如属于 PostComment,有时更新父级的时间戳是有帮助的子模型已更新。例如,当 Comment 模型更新时,您可能希望自动 "touch" 拥有 Postupdated_at 时间戳。 Eloquent 让一切变得简单。只需添加一个包含关系名称的 touches 属性 到子模型:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Comment extends Model {

    /**
     * All of the relationships to be touched.
     *
     * @var array
     */
     protected $touches = ['post'];

    /**
     * Get the post that the comment belongs to.
     */
    public function post()
    {
        return $this->belongsTo('App\Post');
    } }

现在,当您更新 Comment 时,拥有 Postupdated_at 列也会更新,这样可以更方便地知道何时使 Post 的缓存无效Post 型号:

$comment = App\Comment::find(1);

$comment->text = 'Edit to this comment!';

$comment->save();

更新

模型上的删除方法会更新所有者时间戳 方法取自 Illuminate\Database\Eloquent\Model.php

要手动更新,您可以 运行 $this->touchOwners();

public function delete()
{
    if (is_null($this->getKeyName())) {
        throw new Exception('No primary key defined on model.');
    }

    // If the model doesn't exist, there is nothing to delete so we'll just return
    // immediately and not do anything else. Otherwise, we will continue with a
    // deletion process on the model, firing the proper events, and so forth.
    if (! $this->exists) {
        return;
    }

    if ($this->fireModelEvent('deleting') === false) {
        return false;
    }

    // Here, we'll touch the owning models, verifying these timestamps get updated
    // for the models. This will allow any caching to get broken on the parents
    // by the timestamp. Then we will go ahead and delete the model instance.
    $this->touchOwners();

    $this->performDeleteOnModel();

    $this->exists = false;

    // Once the model has been deleted, we will fire off the deleted event so that
    // the developers may hook into post-delete operations. We will then return
    // a boolean true as the delete is presumably successful on the database.
    $this->fireModelEvent('deleted', false);

    return true;
}