Laravel:为历史记录保存我的模型的序列化副本


Laravel: saving a serialized copy of my model for history

我需要管理特定模型的记录历史。按照下面的示例(https://laravel.com/docs/5.2/eloquent#events),我在AppServiceProvider.php文件中做了这样的操作:

use App'SourceModel;
use App'History;
use Illuminate'Support'Facades'Auth;
use Illuminate'Support'ServiceProvider;
class AppServiceProvider extends ServiceProvider {
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        SourceModel::saving(function ($source) {
            $his= new History();
            $his->record = $source->toJson();
            $his->user_id = Auth::User()->id;
            $his->saved_id = $source->id;
            $his->saved_type = 'App'SourceModel';
            $his->save();
        });
    }
...

问题是这样的Auth::User()返回NULL…

我该如何解决这个问题?是否有办法使Auth在appserviceprovider工作,或者我应该把我的保存事件移动到其他地方?

因为这个闭包是在模型保存时调用的,所以假设存在一个经过身份验证的用户,我希望它能够工作。

我可以确认使用tinker:

>>> App'User::saving(function ($user) { echo "AUTH USER ID: " . Auth::user()->id; });
=> null
>>> Auth::login(App'User::find(1));
=> null
>>> App'User::find(1)->save();
AUTH USER ID: 1⏎
=> true

因此,我会说如果Auth::user()返回null,则该模型在没有经过身份验证的用户的情况下保存,如果发生这种情况,则需要添加检查:

    SourceModel::saving(function ($source) {
        $his= new History();
        $his->record = $source->toJson();
        $his->user_id = (Auth::check()) ? Auth::User()->id : 0;
        $his->saved_id = $source->id;
        $his->saved_type = 'App'SourceModel';
        $his->save();
    });

我认为正确的地方听模型事件是EventServiceProvider (App'Providers'EventServiceProvider)。

只要把你的代码移动到EventServiceProvider中的"boot"方法,你就完成了。

<?php
namespace App'Providers;
use Illuminate'Foundation'Support'Providers'EventServiceProvider as ServiceProvider;
use Illuminate'Support'Facades'Event;
use App'SourceModel;
use App'History;
use Illuminate'Support'Facades'Auth;
class EventServiceProvider extends ServiceProvider
{
    /**
     * The event listener mappings for the application.
     *
     * @var array
     */
    protected $listen = [
        'App'Events'SomeEvent' => [
            'App'Listeners'EventListener',
        ],
    ];
    /**
     * Register any events for your application.
     *
     * @return void
     */
    public function boot()
    {
        parent::boot();
        //
        SourceModel::saving(function ($source) {
            $his= new History();
            $his->record = $source->toJson();
            $his->user_id = Auth::User()->id;
            $his->saved_id = $source->id;
            $his->saved_type = 'App'SourceModel';
            $his->save();
        });
    }
}

注意:你可以像这样包含facade: "use 'Auth"