【问题标题】:Laravel 5, log Model create, update , delete eventsLaravel 5,记录模型创建、更新、删除事件
【发布时间】:2018-08-22 23:02:53
【问题描述】:

我正在开发 Laravel 5 应用程序。我想在其中记录所有新的或更改的模型创建、更新和删除事件(如果模型正在更新)模型字段。我想要简单的可重用解决方案,而无需编写太多代码。

【问题讨论】:

    标签: php laravel-5 laravel-5.1


    【解决方案1】:

    当然,您可以像下面这样创建特征并在您要记录的所有模型中使用它。,

    <?php
    
    namespace App\Traits;
    
    use App\Activity;
    use Illuminate\Database\Eloquent\Model;
    
    /**
     * Class ModelEventLogger
     * @package App\Traits
     *
     *  Automatically Log Add, Update, Delete events of Model.
     */
    trait ModelEventLogger {
    
        /**
         * Automatically boot with Model, and register Events handler.
         */
        protected static function bootModelEventLogger()
        {
            foreach (static::getRecordActivityEvents() as $eventName) {
                static::$eventName(function (Model $model) use ($eventName) {
                    try {
                        $reflect = new \ReflectionClass($model);
                        return Activity::create([
                            'user_id'     => \Auth::user()->id,
                            'contentId'   => $model->id,
                            'contentType' => get_class($model),
                            'action'      => static::getActionName($eventName),
                            'description' => ucfirst($eventName) . " a " . $reflect->getShortName(),
                            'details'     => json_encode($model->getDirty())
                        ]);
                    } catch (\Exception $e) {
                        return true;
                    }
                });
            }
        }
    
        /**
         * Set the default events to be recorded if the $recordEvents
         * property does not exist on the model.
         *
         * @return array
         */
        protected static function getRecordActivityEvents()
        {
            if (isset(static::$recordEvents)) {
                return static::$recordEvents;
            }
    
            return [
                'created',
                'updated',
                'deleted',
            ];
        }
    
        /**
         * Return Suitable action name for Supplied Event
         *
         * @param $event
         * @return string
         */
        protected static function getActionName($event)
        {
            switch (strtolower($event)) {
                case 'created':
                    return 'create';
                    break;
                case 'updated':
                    return 'update';
                    break;
                case 'deleted':
                    return 'delete';
                    break;
                default:
                    return 'unknown';
            }
        }
    } 
    

    现在,您可以在要为其抛出事件的任何模型中使用此特征。在您的文章模型中。

    <?php namespace App;
    
    use App\Traits\ModelEventLogger;
    use Illuminate\Database\Eloquent\Model;
    
    class Test extends Model {
    
        use ModelEventLogger;
    
        //Just in case you want specific events to be fired for Article model
        //uncomment following line of code
    
       // protected static $recordEvents = ['created'];
    
    }
    

    当然,您必须创建“活动”模型和具有相关列的相关表。 我希望这会有所帮助。

    【讨论】:

    • 谢谢。我应该把这个特质放在哪里。我需要在特定的地方放置它还是必须在某个地方注册?
    • @Mahesh - 这取决于你。您可以将此特征放在 app 目录中的任何位置。因为它是名称空间的。事实上,从上面的代码很明显,我把它放在带有 App\Traits 命名空间的 app/Traits 目录中,你不必在任何地方注册它。它将使用 Model 自动启动,因为我在 trait 中的函数名称前面放置了 boot 关键字。
    • 这很好,但是我有 $recordEvents 变量的问题,如果我在模型中定义它不起作用,无论如何它是 null @pinkal vansia
    • Created and Updated 工作正常,但 Deleted 模型事件不起作用。
    • 您好 Pinkal,我已经实现了与您建议的相同的类,但它不起作用。我正在使用 laravel 5.4
    【解决方案2】:

    我做了一点修改希望它有所帮助。 (这只是跟踪模型的修改)

    迁移

    <?php
    
    use Illuminate\Database\Migrations\Migration;
    use Illuminate\Database\Schema\Blueprint;
    
    class CreateLogActions extends Migration
    {
      /**
       * Run the migrations.
       *
       * @return void
       */
      public function up()
      {
        Schema::create('log_actions', function (Blueprint $table) {
          $table->increments('id');
          $table->integer('loggable_id');
          $table->string('loggable_type');
          $table->string('action');
          $table->integer('user_id')->unsigned()->index();
          $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
          $table->timestamp('dt_action');
        });
      }
    
      /**
       * Reverse the migrations.
       *
       * @return void
       */
      public function down()
      {
        Schema::drop('log_actions');
      }
    }
    

    型号

    <?php
    
    namespace App\Wdog\Entities;
    
    use Illuminate\Database\Eloquent\Model;
    use Prettus\Repository\Contracts\Transformable;
    use Prettus\Repository\Traits\TransformableTrait;
    
    class LogAction extends Model implements Transformable
    {
      use TransformableTrait;
    
      protected $fillable = [
        'loggable_type',
        'loggable_id',
        'user_id',
        'action',
        'dt_action'
    
      ];
    
      public $timestamps = false;
    
      protected $dates = [
        'dt_action'
      ];
    
      public function user()
      {
        return $this->belongsTo('App\User');
      }
    
      public function loggable()
      {
        return $this->morphTo();
      }
    }
    

    性状

    最后只添加一个特征

    <?php   
    
    namespace App\Wdog\Traits;
    
    use App\Wdog\Entities\LogAction;
    use Auth;
    use Carbon\Carbon;
    use Illuminate\Database\Eloquent\Model;
    
    
    trait ModelEventLogger
    {
    
      public static function bootModelEventLogger()
      {
    
        $user_id = Auth::user()->id;
        foreach (static::getRecordActivityEvents() as $eventName) {
    
    
          static::$eventName(function (Model $model) use ($user_id, $eventName) {
    
            $log = new LogAction([
              'user_id'   => $user_id,
              'dt_action' => Carbon::now(),
              'action'     => $eventName
            ]);          
    
            $model->logs()->save($log);
    
    
          });
        }    
      }    
    
      protected static function getRecordActivityEvents()
      {
        if (isset(static::$recordEvents)) {
          return static::$recordEvents;
        }
    
        return [
          'created',
          'updated',
          'deleted',
        ];
      }
    
    
      protected static function logs()
      {
    
    
        return $this->morphMany('\App\Wdog\Entities\LogAction', 'loggable')->orderBy('dt_action', 'desc');
    
    
    
    
      }
    
    
    }
    

    然后在你的模型中使用特征

    class User extends Model implements Transformable
    {
      use ModelEventLogger;
    ...
    

    【讨论】:

      【解决方案3】:

      虽然是老线程,但具体参考OP对simple reusable solution without writing too much of a code的要求,Spatie's activity logger轻而易举! This specific part 的完整文档展示了 OP 的任务是多么简单易行!

      【讨论】:

      • 非常简单,简单,快速,谢谢!!
      猜你喜欢
      • 1970-01-01
      • 2020-09-28
      • 1970-01-01
      • 2016-08-10
      • 1970-01-01
      • 1970-01-01
      • 2015-09-01
      • 2015-12-07
      • 2020-07-08
      相关资源
      最近更新 更多