Laravel に owen-it/laravel-auditing を入れてDBの更新を監視させつつ、日本語カラムの変更履歴をUnicodeにエスケープさせない方法

owen-it/laravel-auditing を導入すると、DBの更新が、

このようにログに残せるようになります。

自前で Trait を作っても似たような事も出来るんですが、もっと偉い人が作ったモジュールを使っています。

変更のあったカラムの情報だけをきれいに差分をとって記録してくれるのですが、一個だけ大きな欠点が……

日本語の全角文字コードがエスケープされちゃうんですよね(悲しみ)

モデルでJsonカラムに指定されているため、Laravelの方でCastしちゃっているんですが、この問題を回避しつつ、owen-it/laravel-auditing をインストールするところからメモを残しておきます。

owen-it/laravel-auditing のインストール

php composer require owen-it/laravel-auditing

composer を使ってインストールします。

設定ファイルの作成

php artisan vendor:publish --provider "OwenIt\Auditing\AuditingServiceProvider" --tag="config"

これで、configフォルダに audit.php が作成されます。

変更すべき項目は

    'user'      => [
        'morph_prefix' => 'user',
        'guards'       => [
            'web',
            'api',
        ],
        'resolver' => OwenIt\Auditing\Resolvers\UserResolver::class
    ],

guardsで未定義の物が出てくるとエラーになるので、

    'user'      => [
        'morph_prefix' => 'user',
        'guards'       => [
            'user',
            'admin',
        ],
        'resolver' => OwenIt\Auditing\Resolvers\UserResolver::class
    ],

など、環境に合わせたものに変更をする必要があります。
morph_prefixはDBのカラム名だけなのでそのままで問題無し。

CLIからのDB更新も記録したほうがよければ、以下を変更すると良しです。

// 'console' => false,
 'console' => true,

Migrationファイルの作成

php artisan vendor:publish --provider "OwenIt\Auditing\AuditingServiceProvider" --tag="migrations"

で作成されます。

問題なければ、

php artisan migrate

でテーブルを作成します。

app.phpにprovidersを追加

config/app.phpに

'providers' => [

        ....
        ...

        OwenIt\Auditing\AuditingServiceProvider::class,

    ],

これを追加します。

監視対象のモデル設定

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Model;

use OwenIt\Auditing\Contracts\Auditable;

class BaseModel extends Model implements Auditable
{

    use SoftDeletes;
    use \OwenIt\Auditing\Auditable;

上記のような感じで、この3つ追加すると、更新の監視対象になってくれます。

use OwenIt\Auditing\Contracts\Auditable;

implements Auditable

use \OwenIt\Auditing\Auditable;

基底モデルにセットしておくと全モデルを一気に監視対象に出来て便利ですね。

アクセスログを記録するなど、頻繁に更新されるモデルには不向きですが^^

試しにLaravelからDBを更新すると、auditsテーブルにレコードが追加されていると思います。

注意

$this->where('user_id',$user_id)->delete();

こんな感じでdelete処理をコールするとモデルインスタンスを介さずに削除が行われるので、記録が残りません。

なので、

$this->where('user_id',$user_id)->each(function ($row) {
    $row->delete();
});

面倒でもこのようにモデルインスタンスを通してあげる必要があります。

日本語をエスケープさせないようにする

一番のネックだったこれ。

ググってもなかなか方法がほんと見つからない(笑)

Auditのモデルそのもののエスケープを回避させたく、なんとかオーバーライドしようと、あくせく頑張りながらデバッガを走らせていると……環境設定にこんな項目を発見です。

app/audit.php

'implementation' => OwenIt\Auditing\Models\Audit::class,

Auditモデルファイル、指定できるやん(爆)

//    'implementation' => OwenIt\Auditing\Models\Audit::class,
    'implementation' => App\Models\Audit::class,

自前のモデルを指定し、

<?php

namespace App\Models;

use OwenIt\Auditing\Models\Audit as AuditModel;

class Audit extends AuditModel
{
    protected function asJson($value)
    {
        return json_encode($value, JSON_UNESCAPED_UNICODE);
    }
}

OwenIt\Auditing\Models\Audit の asJson をオーバーライドし、JSON_UNESCAPED_UNICODE をエンコード時に追加するようにしてあげました。

これで、

Unicodeエスケープされずに、保管されます。

めでたしめでたし。