在 Laravel 5 中使用模型事件监听器

2023-11-22

我想确保我在 Laravel 5 中正确使用了模型事件监听器,并且没有搞砸任何事情(监听器与处理程序?)。我的解决方案工作正常,但我想知道我是否按照 Laravel 5 的概念和惯例进行开发。

Goal:保存模型时,始终将 $issue->status_id 设置为某个值。

在应用程序\Providers\EventServiceProvider.php

<?php namespace App\Providers;

...

class EventServiceProvider extends ServiceProvider {

    ...

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

        Issue::saving('App\Handlers\Events\SetIssueStatus');
    }

}

在应用程序\Handlers\Events\SetIssueStatus.php

<?php namespace App\Handlers\Events;

...

class SetIssueStatus {

    ...

    public function handle(Issue $issue)
    {
        if (something)
        {   
            $issueStatus = IssueStatus::where(somethingElse)->firstOrFail();
        }
        else 
        {
            $issueStatus = IssueStatus::where(somethingAnother)->firstOrFail();
        }

        // issue_status() is One-to-One relations with IssueType (belongsTo)
        $issue->issue_status()->associate($issueStatus);
    }

}

感谢您的时间。


正如您所说,您有一个工作版本并且它是有效的,现在由您来决定它是否适合您。

只是为了澄清,我并不是说这些是更好的解决方案,它们只是一种有效的不同方式。

由于您正在做的事情是特定于问题模型的,或者至少它看起来不是通用事件,因此您可以直接在模型上设置它

<?php namespace App;

use Illuminate\Database\Eloquent\Model;
use IssueStatus;

class Issue extends Model {


    protected static function boot()
    {
        parent::boot();

        static::saving(function($issue){
            if (something)
            {   
                $issueStatus = IssueStatus::where(somethingElse)->firstOrFail();
            }
            else 
            {
                $issueStatus = IssueStatus::where(somethingAnother)->firstOrFail();
            }

            // issue_status() is One-to-One relations with IssueType (belongsTo)
            $issue->issue_status()->associate($issueStatus);

        });
    }
}

但如果您的事件确实是一个通用事件,并且您想在多个模型中使用它,那么您可以实现相同的目标。您只需要从模型中提取代码并使用特征(就像软删除一样)

首先,我们创建我们的特征(在本例中,我们在应用程序的根目录上创建)并从模型中提取我之前编写的代码:

<?php namespace App

use IssueStatus;

trait IssueStatusSetter
{
    protected static function boot()
    {
        parent::boot();

        static::saving(function($model){
            if (something)
            {   
                $issueStatus = IssueStatus::where(somethingElse)->firstOrFail();
            }
            else 
            {
                $issueStatus = IssueStatus::where(somethingAnother)->firstOrFail();
            }

            // issue_status() is One-to-One relations with IssueType (belongsTo)
            $model->issue_status()->associate($issueStatus);

        });
    }
}

现在,在您想要使用它的模型上,您只需导入该特征并声明它的用途:

<?php namespace App;

use Illuminate\Database\Eloquent\Model;
use IssueStatusSetter;

class Issue extends Model {

    use IssueStatusSetter;

}

现在,我向您展示了最后一个选项,它是一个通用选项,您只需在模型顶部声明它的使用即可将其应用于每个模型。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Laravel 5 中使用模型事件监听器 的相关文章

随机推荐