前回においては、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",
},
],
}
メルマガ購読の申し込みはこちらから。
