模型观察者:stored()和restoring()

时间:2019-10-08 21:43:20

标签: php laravel eloquent

我要在帖子恢复后的 中恢复帖子的注释。

此操作失败:

public function restored(Post $post)
{
    $post->comments()
        ->onlyTrashed()->where('deleted_at', '>=', $post->deleted_at)
        ->get()
        ->each(function ($comment) {
            $comment->restore();
        });
}

这有效:

public function restoring(Post $post)
{
    $post->comments()
        ->onlyTrashed()->where('deleted_at', '>=', $post->deleted_at)
        ->get()
        ->each(function ($comment) {
            $comment->restore();
        });
}

区别是:restoring()而不是restored()

以下情况:where('deleted_at', '>=', $post->deleted_at)在这里,因为我不想恢复在删除帖子之前被软删除的注释。换句话说,我不想恢复主持人软删除的评论。我想恢复被软删除帖子的那一刻被删除的评论。

失败的原因:我相信restored()会失败,因为$post->deleted_at变成了null,所以我不能再以where(...)的条件使用它了。

问题:$post->deleted_at之前的值如何在恢复之前保存?我尝试过与getDirty()getChanges()一起玩,但是这些都无济于事,它们在观察者中没有任何先前的值。

我还尝试了以下方法:

public function restoring(Post $post)
{
    $this->deleted_at = $post->deleted_at;
}

认为它可以让我“坚持” $post->deleted_at的值,并能够在我的restored()方法中使用它。但不是。

我注意到restored()仅恢复第一条评论。就像在某种循环中还原注释后,然后$post->deleted_at因为null(显然,因为它是restored而不是restoring),所以它无法继续还原集合中的其他评论。我认为它引发了错误,因为我猜想循环然后会尝试像where('deleted_at', '>=', null)一样(注意```null``)`。 果然,这确实可行:

public function restored(Post $post)
{
    $post->comments()
        ->onlyTrashed()
        ->get()
        ->each(function ($comment) {
            $comment->restore();
        });
}

(请注意,这是restored(),但我不得不放弃我的where(...),但我确实需要满足where(...)的条件)。

基本上和 TL; DR :如何在我的内部获取$post->deleted_at的“旧”值(即恢复之前的值) public function restoring(Post $post) { }

2 个答案:

答案 0 :(得分:0)

我不确定这是否是理想的方法,但是在某些快速测试中似乎可以使用。如果您希望以这种方式与属性进行交互,还可以在Post模型中设置getter和setter方法。

Post.php

class Post extends Model
{
    // add a custom property with a unique name
    // this will prevent the data from being assigned as an attribute
    public $temp_deleted_at;

    // ...
}

PostObserver.php

public function restoring(Post $post)
{
    // store to custom property
    $post->temp_deleted_at = $post->deleted_at;
}

public function restored(Post $post)
{
    // retrieve from custom property for query
    $post->comments()
        ->onlyTrashed()->where('deleted_at', '>=', $post->temp_deleted_at)
        ->get()
        ->each(function ($comment) {
            $comment->restore();
        });
}

答案 1 :(得分:0)

您应该能够使用response.Redirect("~/")在您的$model->getOriginal('deleted_at')侦听器中检索deleted_at的原始值。