前回においては、Eloquentのbootメソッドを利用してDB変更の情報(監査の情報)を取得することができました。今回は、これをDBに記録する部分を考えてみましょう。
監査のデータを保存するテーブル
監査のデータを保存するテーブルを、audit_logsとしてmigrationファイルを作成します。
$ php artisan make:migration create_audit_logs_table Created Migration: 2020_05_20_024714_create_audit_logs_table
作成されたファイルを編集して、テーブルの項目定義を入れます。
use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class CreateAuditLogsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('audit_logs', function (Blueprint $table) { $table->bigIncrements('id'); $table->unsignedBigInteger('user_id')->default(0)->index(); // Userモデルのid $table->string('path')->default(''); // 実行したプログラムのパス名 $table->longText('old_value')->nullable(); // 変更前の値 $table->longText('new_value')->nullable(); // 変更後の値 $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('audit_logs'); }
old_valueとnew_valueには、レコードの項目のすべての値をserializeして入れるために大きいデータタイプとしています。
以下を実行してテーブルを作成します。
$ php artisan migrate Migrating: 2020_05_20_024714_create_audit_logs_table Migrated: 2020_05_20_024714_create_audit_logs_table (0.02 seconds)
AuditLogのクラスも作成します。
namespace App; use Illuminate\Database\Eloquent\Model; class AuditLog extends Model { protected $guarded = []; }
そして、Userクラスのプログラムを書き替えます。
namespace App; use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Request; class User extends Authenticatable { use Notifiable; /** * The attributes that are mass assignable. * * @var array */ protected $fillable = [ 'name', 'email', 'password', ]; /** * The attributes that should be hidden for arrays. * * @var array */ protected $hidden = [ 'password', 'remember_token', ]; /** * The attributes that should be cast to native types. * * @var array */ protected $casts = [ 'email_verified_at' => 'datetime', ]; protected static function boot() { parent::boot(); static::created(function ($model) { AuditLog::create([ 'user_id' => $model->id, 'path' => Request::path(), 'old_value' => null, 'new_value' => serialize($model->attributes), ]); }); static::updated(function ($model) { AuditLog::create([ 'user_id' => $model->id, 'path' => Request::path(), 'old_value' => serialize($model->original), 'new_value' => serialize($model->attributes), ]); }); static::deleted(function ($model) { AuditLog::create([ 'user_id' => $model->id, 'path' => Request::path(), 'old_value' => serialize($model->original), 'new_value' => null, ]); }); } }
tinkerでレコードの作成、Eメールアドレスの変更、そしてレコードの削除を実行します。
Psy Shell v0.10.2 (PHP 7.2.16 — cli) by Justin Hileman >>> use App\AuditLog; >>> $user = User::create(['name' => 'name1', 'email' => 'test1@example.com', 'password' => 'test']); [!] Aliasing 'User' to 'App\User' for this Tinker session. => App\User {#3058 name: "name1", email: "test1@example.com", updated_at: "2020-05-20 03:28:18", created_at: "2020-05-20 03:28:18", id: 1, } >>> $user->update(['email' => 'test2@example.com']); => true >>> $user->delete(); => true
AuditLogのレコードを取り出してみると、すべてのの変更履歴、監査の情報が保存されています。
>>> AuditLog::all(); => Illuminate\Database\Eloquent\Collection {#3072 all: [ App\AuditLog {#3073 id: 1, user_id: 1, path: "/", old_value: null, new_value: "a:6:{s:4:"name";s:5:"name1";s:5:"email";s:17:"test1@example.com";s:8:"password";s:4:"test";s:10:"updated_at";s:19:"2020-05-20 03:28:18";s:10:"created_at";s:19:"2020-05-20 03:28:18";s:2:"id";i:1;}", created_at: "2020-05-20 03:28:18", updated_at: "2020-05-20 03:28:18", }, App\AuditLog {#3074 id: 2, user_id: 1, path: "/", old_value: "a:6:{s:4:"name";s:5:"name1";s:5:"email";s:17:"test1@example.com";s:8:"password";s:4:"test";s:10:"updated_at";s:19:"2020-05-20 03:28:18";s:10:"created_at";s:19:"2020-05-20 03:28:18";s:2:"id";i:1;}", new_value: "a:6:{s:4:"name";s:5:"name1";s:5:"email";s:17:"test2@example.com";s:8:"password";s:4:"test";s:10:"updated_at";s:19:"2020-05-20 03:28:38";s:10:"created_at";s:19:"2020-05-20 03:28:18";s:2:"id";i:1;}", created_at: "2020-05-20 03:28:38", updated_at: "2020-05-20 03:28:38", }, App\AuditLog {#3075 id: 3, user_id: 1, path: "/", old_value: "a:6:{s:4:"name";s:5:"name1";s:5:"email";s:17:"test2@example.com";s:8:"password";s:4:"test";s:10:"updated_at";s:19:"2020-05-20 03:28:38";s:10:"created_at";s:19:"2020-05-20 03:28:18";s:2:"id";i:1;}", new_value: null, created_at: "2020-05-20 03:28:47", updated_at: "2020-05-20 03:28:47", }, ], }メルマガ購読の申し込みはこちらから。