在 Laravel 5 中使用模型事件侦听器
Using Model Events Listener in Laravel 5
我想确保我在 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;
}
现在我向您展示的最后一个选项是一个通用选项,您只需声明它在模型的顶部使用即可应用于每个模型。
我想确保我在 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;
}
现在我向您展示的最后一个选项是一个通用选项,您只需声明它在模型的顶部使用即可应用于每个模型。