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

zss*_*890 10 php laravel eloquent

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

目标: 当模型保存时,始终将$ issue-> status_id设置为某个值.

在app\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');
    }

}
Run Code Online (Sandbox Code Playgroud)

在app\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);
    }

}
Run Code Online (Sandbox Code Playgroud)

感谢您的时间.

Fab*_*nes 16

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

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

由于您所做的是特定于问题模型或至少它似乎不是一般事件,您可以直接在您的模型上设置它

<?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);

        });
    }
}
Run Code Online (Sandbox Code Playgroud)

但是如果你的活动确实是一般的,你想在多个模型中使用它,你可以实现同样的目的.您只需要从模型中提取代码并使用特征(就像使用软删除一样)

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

<?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);

        });
    }
}
Run Code Online (Sandbox Code Playgroud)

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

<?php namespace App;

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

class Issue extends Model {

    use IssueStatusSetter;

}
Run Code Online (Sandbox Code Playgroud)

现在,我向您展示了这个最后一个选项,它是一个通用选项,您可以通过声明它在模型顶部的使用来应用于每个模型.