Laravel 5.1模型删除事件

时间:2015-11-10 09:36:27

标签: php laravel polymorphism laravel-5.1

我有很多模特。用户可以对某些模型记录进行评论。例如,用户可以对通知模型记录发表评论,或者用户可以对日历模型记录发表评论。

我创建了一个名为trait的{​​{1}}。这包含了根据模型检索注释,添加/删除注释,创建注释创建表单等所需的所有方法。

每当我想要一个可评论的模型时,我需要做的就是在模型中使用该特征。

因为该评论是与模型记录的多态关系,所以我无法进行Commentable迁移。

每当删除父模型(例如通知或日历项)时,我也希望删除所有相关记录,但我不想依赖开发人员编写{{ 1}}方法调用重写的删除函数。

我以为我会创建一个服务提供程序来监听任何模型删除事件,检查该模型是否可评论,并删除任何相关的注释,但事件没有正确触发。

这是我的服务提供商代码:

onCascade = delete

如您所见,它只是检查已删除的模型以查看它是否使用deleteRelatedComments()特征。如果是,则调用Model::deleting(function (Model $record) { if(in_array('App\Libraries\Traits\Commentable', class_uses($record))) { $record->deleteRelatedComments(); } return true; }); 方法。

我的问题

有没有办法在删除它的父记录时自动删除相关的多态相关内容:

如果我删除Commentable条记录,是否有办法删除任何关联的多态deleteRelatedComments()记录?

1 个答案:

答案 0 :(得分:2)

我之前创建了一个服务提供程序,以使用http://laravel.com/docs/5.1/eloquent#events

中指定的模型事件来侦听任何模型删除

但是,如果您尝试收听Model课程而不是Notice等特定课程,则此功能无效。

相反,当您删除每个模型时,会触发eloquent.deleting事件。然后我可以在EventServiceProvider中手动创建一个监听器来监听任何被删除的模型,并相应地执行我的检查,但不依赖于用户重载delete()方法并手动删除多态关系。

<强>答案

如果要在删除模型时自动删除多态内容,请确保在模型中实现接口或使用特征。

例如,我想在删除父模型记录时删除所有多态注释(如果我删除了一条通知记录,则删除所有多态注释)。

我创建了一个Commentable特征,我在任何模型中使用它(但你可以很容易地使用模型上的空接口)。

然后,在EventServiceProvider.php相应地更改boot()方法:

public function boot(DispatcherContract $events)
{
    parent::boot($events);

    /**
     * If you use a trait in your model:
     */
    $events->listen('eloquent.deleting*', function ($record) {
        if (in_array('App\Libraries\Traits\Commentable', class_uses($record))) {
            $record->deleteRelatedComments();
        }
    });


    /**
     * Or if you use an interface:
     */

    $events->listen('eloquent.deleting*', function ($record) {
        if ($record instanceof SomeInterface) {
            $record->deleteSomePolymorphicRelation();
        {
    });
}

使用案例

可评论的特质

namespace App\Libraries\Traits;


trait Commentable 
{
    public function comments()
    {
        return $this->morphMany(Comment::class, 'content');
    }

    public function deleteRelatedComments()
    {
        $this->comments()->delete();
    }
}

可评论模型

class Notice extends Model
{
    use Commentable;

    /** ... **/

    /**
     * NOTE: You do not need to overload the delete() method
     */
}

<强> EventServiceProvider.php

public function boot(DispatcherContract $events)
{
    parent::boot($events);

    $events->listen('eloquent.deleting*', function ($record) {
        if (in_array('App\Libraries\Traits\Commentable', class_uses($record))) {
            $record->deleteRelatedComments();
        }
    });
}

现在,开发人员创建一个希望它可评论的新内容类型,不需要担心创建关系,管理关系方法,甚至通过重载delete()来删除多态内容。要使模型完全可注释,他们只需要使用Commentable特征,框架就可以处理所有内容。

只要父模型实现某个接口或使用相关特征,此方法可用于自动删除任何多态记录。