我有很多模特。用户可以对某些模型记录进行评论。例如,用户可以对通知模型记录发表评论,或者用户可以对日历模型记录发表评论。
我创建了一个名为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()
记录?
答案 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
特征,框架就可以处理所有内容。
只要父模型实现某个接口或使用相关特征,此方法可用于自动删除任何多态记录。