← Back to Blog List

Laravelでデータの変更履歴用トレイトをつくる

内容:Laravelでデータの変更箇所を追跡する方法です。

なぜ書いたか:現場で変更履歴を表示させる処理が必要になったから。備忘録です。 Laravel Auditingというパッケージもありますが、今回はトレイトの作成にしました。

※記事では各ファイル作成コマンドの記載は省きます。 コマンドの一覧はこちらの記事をご参考ください!


① 履歴変更保存用のテーブルをデータベースに作成する

  • 話のメインになる項目は下記3つ。
    • カラム名を取得する'column_name'
    • 古い値を取得する'old_value'
    • 新しい値を取得する'new_value'

② モデルの作成

//namespaceとかuseとか
class ChangedHistory extends Model
{   
   protected $table = 'changed_history'; //テーブル名

   protected $fillable = [
       'id',
       'column_name',
       'old_value',
       'new_value',
       'created_at',
   ];
}

こんな感じです。

③ トレイトの作成

  • \app\Traitsに作成。この場合はHasChangedHistory.phpにします。
//namespaceとかuseとか
trait HasChangedHistory
{
    public static function bootHasChangedHistory()
    {
        //updatedの時に動作する
        static::updated(function ($model) {
            //トレイト内の処理()を指定しています。
            $model->recordChangedHistory('updated');
        });
        /*createdやdeletedでも動作させたい場合は

            static::created(function ($model){
                このように追記
            });        
       
         */
    }

    public function recordChangedHistory($event)
    {   //DBの差分を取得するメソッドgetChanges()
        $changedAttributes = $this->getChanges(); 
        //連想配列を処理する
        foreach ($changedAttributes as $column_name => $newValue) {
            //変更前の値を取得するメソッドgetOriginal()
            $oldValue = $this->getOriginal($column_name);
            $changeHistory = \ChangedHistory::create([
                'id' => $this->id,
                'column_name' => $column_name,
                'old_value' => $oldValue,
                'new_value' => $newValue,
            ]);
        }
    }   
}

④ 変更を追跡したいモデルに追記する

//色々なuse
use App\Traits\HasChangedHistory; //こちら!!!

class Foo extends Model
{
    //色々なuse
    use HasChangedHistory; //こちら!!!

上記設定をして、対象テーブルを変更するとchanged_historyテーブルに行が追加されているかと思います。

おわり


参考にした記事

また、初めてQiitaに投稿するので下記にも大変力をいただきました! :tiger: