背景
保存するデータに変更がなくても updated_at を更新してほしいケースがあって、
こちらの記事 を参考に実装してみたけど、update()でも updated_at が更新されず。
バージョン差分とかで変わったのかなと思い調べてみました。
ちなみにデバッグしてたのは Laravel 5.7 です。(古いバージョンの情報ですみません...)
結論
save(), update() のどちらも同じ。
- 保存するデータに差分があれば
updated_atは更新される。 - 保存するデータに差分がなければ
updated_atは更新されない。
詳細
コードを見てみる。
save()
データに変更があるかチェックしてる。
$saved = $this->isDirty() ?
$this->performUpdate($query) : true;
update()
return $this->fill($attributes)->save($options);
結局 save() 呼んでるやん!
Laravel 8 でもコードは同じでした。
https://github.com/illuminate/database/blob/8.x/Eloquent/Model.php
じゃあ updated_at を更新したいときは?
$model->touch();
これでOK!
まとめ
久しぶりにLaravel(というかEloquent)のコードを見たので、たまには書いてみました。
参考: 背景の詳細と課題
なんで updated_at を更新したかったかというと、
プログラム上は1つのオブジェクトだけど、DBのテーブルは2つに分かれている、というオブジェクトを扱いたかったから。
(商品マスターテーブルとその属性テーブルみたいな感じ)
このオブジェクトの更新日データはマスター側の updated_at を参照してたんだけど、属性テーブルのデータしか更新が発生しなかった時に、更新したのにソート順が変わらない、みたいなことが起きました。
画面上は更新ボタンを押すので、商品マスターテーブルの更新は毎回 updated_at が更新されるようにしてもいいかな、と考えてこの記事に書いたことを調べてました。
もっといい方法はないのか
(ここはちょっとメモです)
テーブルはあくまで2つとしたとき、どうするのが良かったのかな〜。
↓こんな感じ?
- Aを
save() - Bを
save() - Bが更新されてたら、Aを
touch()してsave() - Bが更新されてなかったら、何もしない
Aを2回save()は無駄な感じがします。。。
- Aを
fill()まで - Bを
save() - Bが更新されてたら、Aを
touch()してsave() - Bが更新されてなかったら、Aを
save()
これなら少しDBアクセス減りますね。