Laravel Eloquent 事件 - 更新后保存模型
Laravel Eloquent Events - implement to save model if Updated
我在控制器中有这样的代码:
for($i=0; $i<$number_of_tourists; $i++) {
$tourist = Tourist::updateOrCreate(['doc_number' => $request['doc_number'][$i]],
$tourist_to_update);
}
因此,updateOrCreate 方法可以 1) 更新记录,2) 创建新记录 3) 如果 $tourist_to_update 等于数据库中已有的记录,则保持记录不变。
我想将 $tourist_to_update 保存到 $array[] 中,仅当正在更新“游客”table 中的记录时(而不是当已创建新记录或没有任何变化)。
据我所知,有 Eloquent 事件 https://laravel.com/docs/5.4/eloquent#events 有 updating 和 updated 事件,似乎符合我的需求。
问题是我看了几个教程,但仍然不明白如何使用它们。
我知道如何在 Tourist 模型中注册 Eloquent 事件:
protected static function boot()
{
parent::boot();
static::updating(function ($model) {
});
}
谁能解释一下我如何通过 Eloquent 事件实现我的目标?
提前致谢。
如果模型已创建,属性 wasRecentlyCreated
将设置为 true,因此您可以通过以下方式检查模型是新的还是更新的:
$updated = [];
for($i = 0; $i < $number_of_tourists; $i++) {
$currentTourist = ['doc_number' => $request['doc_number'][$i]];
$tourist = Tourist::updateOrCreate($currentTourist, $tourist_to_update);
if ( $tourist->wasRecentlyCreated ) {
continue; // Go to next loop if this tourist was created now
}
$updated[] = $tourist;
}
这是一种稍微复杂一些的方法,但如果您只想获取数据已更改的更新记录,这是可行的。在您的控制器方法中添加:
app()->singleton('touristsCollector', function ($app) {
$collector = new \stdClass;
$collector->updated = [];
return $collector;
});
for($i = 0; $i < $number_of_tourists; $i++) {
$tourist = Tourist::updateOrCreate(
['doc_number' => $request['doc_number'][$i]],
$tourist_to_update
);
}
$collector = resolve('touristsCollector');
var_dump( $collector->updated ); // Only updated tourists which have data changed
这基本上会向应用程序容器添加一个标准 PHP class,它将收集模型事件中所有更新的游客。在您的模型中添加:
protected static function boot()
{
parent::boot();
static::updated(function ($model) {
$collector = resolve('touristsCollector');
$collector->updated[] = $model;
});
}
这基本上会从应用程序容器中获取 PHP class,仅当其某些属性已更新时添加游客模型。
如果你总是想在 tourist table 中的一行更新时执行特定代码,我建议创建一个 observer 来监听 updated
或 create
来电。
<?php
namespace App\Observers;
use App\Tourist;
class TouristObserver
{
/**
* Listen to the User created event.
*
* @param \App\User $user
* @return void
*/
public function created(Tourist $user)
{
// this will always trigger when you created a new entry
}
/**
* Listen to the User deleting event.
*
* @param \App\Tourist $user
* @return void
*/
public function updated(Tourist $user)
{
// this will always trigger when actually a row was updated
}
}
您所要做的就是像这样在 AppServiceProvider
中注册观察者:
public function boot()
{
Tourist::observe(\App\Observer\TouristObserver::class);
}
我在控制器中有这样的代码:
for($i=0; $i<$number_of_tourists; $i++) {
$tourist = Tourist::updateOrCreate(['doc_number' => $request['doc_number'][$i]],
$tourist_to_update);
}
因此,updateOrCreate 方法可以 1) 更新记录,2) 创建新记录 3) 如果 $tourist_to_update 等于数据库中已有的记录,则保持记录不变。
我想将 $tourist_to_update 保存到 $array[] 中,仅当正在更新“游客”table 中的记录时(而不是当已创建新记录或没有任何变化)。
据我所知,有 Eloquent 事件 https://laravel.com/docs/5.4/eloquent#events 有 updating 和 updated 事件,似乎符合我的需求。
问题是我看了几个教程,但仍然不明白如何使用它们。
我知道如何在 Tourist 模型中注册 Eloquent 事件:
protected static function boot()
{
parent::boot();
static::updating(function ($model) {
});
}
谁能解释一下我如何通过 Eloquent 事件实现我的目标?
提前致谢。
如果模型已创建,属性 wasRecentlyCreated
将设置为 true,因此您可以通过以下方式检查模型是新的还是更新的:
$updated = [];
for($i = 0; $i < $number_of_tourists; $i++) {
$currentTourist = ['doc_number' => $request['doc_number'][$i]];
$tourist = Tourist::updateOrCreate($currentTourist, $tourist_to_update);
if ( $tourist->wasRecentlyCreated ) {
continue; // Go to next loop if this tourist was created now
}
$updated[] = $tourist;
}
这是一种稍微复杂一些的方法,但如果您只想获取数据已更改的更新记录,这是可行的。在您的控制器方法中添加:
app()->singleton('touristsCollector', function ($app) {
$collector = new \stdClass;
$collector->updated = [];
return $collector;
});
for($i = 0; $i < $number_of_tourists; $i++) {
$tourist = Tourist::updateOrCreate(
['doc_number' => $request['doc_number'][$i]],
$tourist_to_update
);
}
$collector = resolve('touristsCollector');
var_dump( $collector->updated ); // Only updated tourists which have data changed
这基本上会向应用程序容器添加一个标准 PHP class,它将收集模型事件中所有更新的游客。在您的模型中添加:
protected static function boot()
{
parent::boot();
static::updated(function ($model) {
$collector = resolve('touristsCollector');
$collector->updated[] = $model;
});
}
这基本上会从应用程序容器中获取 PHP class,仅当其某些属性已更新时添加游客模型。
如果你总是想在 tourist table 中的一行更新时执行特定代码,我建议创建一个 observer 来监听 updated
或 create
来电。
<?php
namespace App\Observers;
use App\Tourist;
class TouristObserver
{
/**
* Listen to the User created event.
*
* @param \App\User $user
* @return void
*/
public function created(Tourist $user)
{
// this will always trigger when you created a new entry
}
/**
* Listen to the User deleting event.
*
* @param \App\Tourist $user
* @return void
*/
public function updated(Tourist $user)
{
// this will always trigger when actually a row was updated
}
}
您所要做的就是像这样在 AppServiceProvider
中注册观察者:
public function boot()
{
Tourist::observe(\App\Observer\TouristObserver::class);
}