Laravel Eloquent Events - 如果更新,则实施保存模型

时间:2017-08-15 17:55:45

标签: laravel-events

我在控制器中有这样的代码:

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 []中,只有当一个记录在&#39; tourist&#34;表正在更新(不是在创建新记录或没有更改时)。

据我所知,有一些Eloquent事件https://laravel.com/docs/5.4/eloquent#events更新更新的事件,似乎符合我的需要。

问题是我看过并阅读了几个教程,但仍然不了解如何使用它们。

我知道如何在旅游模型中注册一个Eloquent事件:

protected static function boot()
{
    parent::boot();

    static::updating(function ($model) {

    });
}

任何人都可以解释我如何通过Eloquent事件实现我的目标?

提前谢谢。

3 个答案:

答案 0 :(得分:1)

这是一种更复杂的方法,但是如果您只想获得更新数据的更新记录,那么这是有效的。在你的控制器方法中添加:

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

这将基本上为app容器添加一个标准的PHP类,它将从模型事件中收集所有更新的游客。在你的模型中添加:

protected static function boot()
{
    parent::boot();

    static::updated(function ($model) {
        $collector = resolve('touristsCollector');
        $collector->updated[] = $model;
    });
}

这将基本上从应用程序容器中获取PHP类,只有在其某些属性已更新时才添加旅游模型。

答案 1 :(得分:0)

如果已创建模型,则属性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;
}

答案 2 :(得分:0)

如果您总是希望在旅游表格中的行更新时执行特定代码,我建议您创建一个observer来收听updatedcreate来电。

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