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

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

}

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

}

感谢您的宝贵时间。

最佳答案

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

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

由于您正在做的事情是特定于 Issue 模型的,或者至少它似乎不是一个通用事件,您可以直接在您的模型上设置它

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

}

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

关于php - 在 Laravel 5 中使用模型事件监听器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29818317/

相关文章:

javascript - 使用 Javascript 运行 php 脚本来检查用户名

PHP、MYSQL 检查用户是否是页面的所有者

laravel - laravel护照和 flutter 打如何工作

php - laravel 如何添加一对一关系

php - Laravel 5 - 多对多关系 - 获取枢轴数据

php - reCAPTCHA 和 PHP 发送电子邮件表单

php - 如何在正则表达式后面实现可变宽度查找来获取项目列表?

laravel - 如何将航海者的东西迁移到新的部署实例?

php - Laravel 获取没有附加属性的模型

laravel - Laravel Eloquent 中的动态关系查询