LoginSignup
4
1

[Laravel] レコードの更新でupdated_atを自動更新させない

Last updated at Posted at 2021-11-17

やりたいこと

表題の通り、where句などで条件で絞ったレコードを指定カラムのみで一括更新したい。

実行環境

Laravel 5.7
注意:他のバージョンでは、別の実装方法で解決ができるかもしれません。

結論

Eloquentを利用せずに、クエリビルダを仕様して更新(update)をする。
クエリビルダではデータベースを直接操作可能になるので、Eloquentを利用するときのEloquentモデル規約などは反映されずに更新したいカラム以外のupdated_at(timestamp型)は更新されなくなる。

sample.php
DB::table('item')->where('status', 1)->update(['status' => 2]);

検討した実装方法

Eloquentを利用したupdate

特定のカラムの更新のみをしたいときにエレクエントを利用したupdate処理。
itemsテーブルのstatus = 1status = 2に更新させたい。
以下のようにするとstatus = 2に更新はできますが、同時にtimestamps型のupdated_atも更新されてしまいます。

sample.php
Item::where('status', 1)->update(['status' => 2]);

ドキュメントにも記載されてます。

デフォルトでEloquentはデータベース上に存在するcreated_at(作成時間)とupdated_at(更新時間)カラムを自動的に更新します。これらのカラムの自動更新をEloquentにしてほしくない場合は、モデルの$timestampsプロパティをfalseに設定してください。
タイムスタンプ

この設定をしてしまうとEloquent全体に適応されてしまうので、今回みたいに一部でのみupdated_atを利用したくない場合は使えませんでした。

saveメソッドでの更新

saveメソッドも自動でupdate_atは自動更新されますが、明示的に$item->timestamps = falseとすることで自動更新されなくなります。今回は一括で更新したい。バッチ処理だとクエリ数が多くなるのでこちらも使えませんでした。

sample.php
$item = Item::where('status', 1)->first();
$item->status = 2;
$item->timestamps = false;
$item->save();

まとめ

普段はEloquentを利用したレコード操作多くて、クエリビルダを全然使ってなかったので解決までに時間がかかりました。。。

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