使用事件侦听器优化分离模型

时间:2020-07-01 14:41:39

标签: php laravel

我具有销毁功能,可让我分离模型(多态关系)。

data.append('file', document.getElementById('file').files[0]);

在这里,我使用“ detachCategories”(帮助我分离类别的助手)分离“事件”模型

我收集它们,并进行前瞻。它可以正常工作,并且与我的表public function destroy { $vaccine = HealthItem::findOrFail($vaccine_id); $vaccine->detachCategories(); $events = $vaccine->events()->get(); foreach ($events as $event) { $event->detachCategories(); }; $vaccine->events()->delete(); $vaccine->delete(); } 完全分开。

但是我认为那不是很好,对吧?

每当一个模型链接到我的categorizable时,我都必须这样做,它会做很多事情。因此,我试图使它成为一个事件,但没有成功。

我的事件模型:

events

我用以下行protected static function boot() { parent::boot(); static::deleting(function ($event) { $event->categories()->detach(); }); } 删除event

你会怎么做?

1 个答案:

答案 0 :(得分:0)

Laravel Events应该可以帮助您,如果这很重要,并且在服务器上设置了队列工作器,则应确保事件侦听器已排队。

以下解决方案应该起作用:

您可能希望为此多态关系订立合同和特征,以便您可以更好地进行类型提示,并干燥代码。您可以将它们放在最适合您项目的文件夹中。说:

interface CategorizableContract
{
   // Relationship to access the models categories
}

trait HasCategories
{
    // Implement methods above
  
    /**
     * Initialize the trait
     *
     * @return void
     */
    protected function bootHasCategories()
    {
        static::deleting(function($categorizable) {
            event(new DestroyCategorizable($categorizable));
        });
    }
}

然后在模型中具有以下类别:

class Vaccine extends Model implements CategorizableContract
{
   use HasCategories;
   ...
}

现在我们可以在App \ Events中创建一个事件:

class DestroyCategorizable
{
    use SerializesModels;
    
    /** @var CategorizableContract */
    public $categorizable;

    /**
     * Create an event for deleting categorizable models
     * 
     * @param CategorizableContract $categorizable
     *
     * @return void 
     */
    public function __construct(CategorizableContract $categorizable)
    {
        $this->categorizable = $categorizable;
    }
}

现在,您可以在App \ Listeners中创建事件侦听器,如下所示:

class DetachCategories implements ShouldQueue
{
    public function handle(DestroyCategorizable $event)
    {
         $categorizable = $event->categorizable;
         $class = new ReflectionClass($categorizable)

         // Detach the categories
         DB::table('categorizable')
             ->where('categorizable_type', $class->getName())
             ->where('categorizable_id', $categorizable->id)
             ->delete();
    }
}

现在只需在EventServiceProvider中注册您的侦听器,然后您就可以离开!

    protected $listen = [
        DestroyCategorizable::class => [
            DetachCategories::class,
        ],
    ];

现在,当您在具有类别的模型上调用删除时,它将自动为您分离它们。

    $vaccine->delete();

即使模型已删除,它也会在事件中进行序列化,因此可以使用其ID和类类型来分离侦听器中的类别。希望能有所帮助:)