在Laravel中使用模型事件监听器5 [英] Using Model Events Listener in Laravel 5

查看:155
本文介绍了在Laravel中使用模型事件监听器5的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想确保我正确地使用了Laravel 5中的模型事件监听器,我没有弄乱(监听器与处理程序)。我的解决方案工作正常,但我不知道我是否按照Laravel 5的概念和惯例开发。



目标:
始终设置$ issue-> status_id在保存模型时的某些值。



在app \Providers\EventServiceProvider.php中

 <?php命名空间App \Providers; 

...

class EventServiceProvider extends ServiceProvider {

...

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

发布::保存('App \Handlers\Events\SetIssueStatus');
}

}

在app \Handlers\事件\SetIssueStatus.php

 <?php命名空间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()与IssueType(belongsTo)的一对一关系
$ issue-> issue_status() - > associate($ issueStatus) ;
}

}

谢谢你的时间。 / p>

解决方案

正如你所说,你有一个工作版本,它是一个有效的版本,现在由你决定是否可以



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



由于您正在做的是特定于问题模型,或至少它似乎不是通用事件,您可以直接在模型上进行设置。

 <?php命名空间应用程序; 

使用Illuminate\Database\Eloquent\Model;
使用IssueStatus;

类问题扩展模型{


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()与IssueType(belongsTo)一对一关系
$ issue-> issue_status() - > associate($ issueStatus);

}) ;
}
}

但如果你的活动确实是一个普通的,你想要跨多个模型使用它,你可以实现同样的事情。您只需从模型中提取代码并使用traits(如同软删除一样)



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

 <?php命名空间App 

使用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()与IssueType(belongsTo)一对一关系
$ model-> issue_status() - > associate($ issueStatus);

}) ;
}
}

现在,在要使用它的模型上,你只是导入trait并声明它使用:

 <?php命名空间应用程序; 

使用Illuminate\Database\Eloquent\Model;
使用IssueStatusSetter;

类问题扩展模型{

use IssueStatusSetter;

}

现在这个最后一个选项我告诉你这是一个通用的选项您可以通过在模型顶部声明它来使用每个模型。


I would like to make sure that I correctly used model events listeners in Laravel 5 and I didn't messed up nothing (listener vs handler?). My solution works fine, but I wonder if I developed according to concept and convention of Laravel 5.

Goal: Always set $issue->status_id on some value when model is saving.

In 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');
    }

}

In 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);
    }

}

Thank you for your time.

解决方案

As you said you have a working version and it's a valid one, now that's up to you to figure out if it's ok for you.

Just to clarify I'm not saying that these are better solutions, they are just a valid different way.

Since what you are doing is specific to the Issue model or at least it doesn't seem to be a generic event, you could set it up on your model directly

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

        });
    }
}

but if your event is indeed a generic one and you want to use it across multiple Models, you could achieve the same thing. You just need to extract the code from the model and use traits (like you do with soft deletes)

First we create our trait(in this case we created on the root of our App) and extract the code, I wrote before, from the model:

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

        });
    }
}

Now on the models where you want to use it, you just import the trait and declare it's use:

<?php namespace App;

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

class Issue extends Model {

    use IssueStatusSetter;

}

Now this last option I showed you it's a generic option you have that you could apply to every Model by just declaring it's use on the top of your model.

这篇关于在Laravel中使用模型事件监听器5的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆