4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Eloquentのsave()とupdate()の`updated_at`の扱い

Last updated at Posted at 2021-10-02

背景

保存するデータに変更がなくても 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つとしたとき、どうするのが良かったのかな〜。
↓こんな感じ?

  1. Aをsave()
  2. Bをsave()
  3. Bが更新されてたら、Aをtouch()してsave()
  4. Bが更新されてなかったら、何もしない

Aを2回save()は無駄な感じがします。。。

  1. Aをfill()まで
  2. Bをsave()
  3. Bが更新されてたら、Aをtouch()してsave()
  4. Bが更新されてなかったら、Aをsave()

これなら少しDBアクセス減りますね。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?