Laravel Eloquentを使ってた時に・・・
- timestampsを全部無効化したい
- updated_atカラムだけいらない
- created_atカラムだけ使いたい
こういう場面がありました。
ただそのコードを書くのが分かりにくかった
そこで自分への記憶補強も兼ね、
Laravelでtimestampsを無効化する手順を紹介します。
※ Laravel 8だけど恐らくどのバージョンでもOK
このページの目次
テーブルのtimestampsを全無効化するのは簡単
何でもいいけど次のテーブルを作ったとします。
▼ migrationファイルの記述
1 2 3 4 5 6 |
Schema::create('posts', function (Blueprint $table) { $table->id(); $table->unsignedBigInteger('user_id'); $table->text('content'); $table->timestamps(); }); |
この時 $table->timestamps() を呼び出すことで created_atカラムとupdated_atカラムが自動で作られます。そして作成時・更新時にそれぞれ更新してくれます。
その機能自体は便意なんだけど、テーブルによってはcreated_atだけが必要だったり、あるいは両方ともいらないみたいな場面は多いですよね。
両方いらない場合は次で変更可能です。
▼ migrationファイルの記述変更
1 2 3 4 5 6 |
Schema::create('posts', function (Blueprint $table) { $table->id(); $table->unsignedBigInteger('user_id'); $table->text('content'); //$table->timestamps(); }); |
▼ Modelクラスでこうする
1 2 3 4 5 6 7 |
class Post extends Model { use HasFactory; protected $table = 'posts'; public $timestamps = false; } |
もし既にcreated_atカラム・updated_atカラムがあるなら新しく make:migration をして、それらを削除してください。
そしてModelを継承したクラスで public $timestamps = false; の1行を追加すればいいだけです。こうしておかないと作成時・更新時にエラーが出るので要注意
timestampsの一部(updated_at)だけ無効化するには
ここではupdated_atカラムが不要でした。
▼ そこでまずは次のようにテーブル作成
1 2 3 4 5 6 7 |
Schema::create('posts', function (Blueprint $table) { $table->id(); $table->unsignedBigInteger('user_id'); $table->text('content'); $table->timestamps(); $table->dropColumn('updated_at'); }); |
このように $table->dropColumn('updated_at'); としてupdated_atカラムをドロップしておきます。これでcreated_atカラムだけ残るという訳
でもLaravelではこの処理だけでは不十分で、Modelクラスでさらに一工夫してあげないといけません。具体的にはModelクラスで変更が必要ですね。
▼ Modelクラスで一工夫する
1 2 3 4 5 6 7 8 9 10 |
class Post extends Model { use HasFactory; /// ▼ これを追加 const UPDATED_AT = null; protected $table = 'posts'; public $timestamps = true; } |
これが分からなくて少し困ってました。
※ コメントのご指摘により一部修正
単純に const UPDATED_AT = null; を追加するだけだけど、ググると色々情報が出てきて困惑。最終的にはこれが期待通りの動作になったので良かったです。
ちなみにModel側でupdated_atを無効化しないとエラー発生
ちなみにModel側で対策しないとどうなるかについて
▼ こういうエラーが出る
1 |
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'updated_at' in 'field list' (SQL: insert into `posts` (`user_id`, `updated_at`, `created_at`) values (3, 2021-08-12 02:21:44, 2021-08-12 02:21:44)) exception : Illuminate\\Database\\QueryException |
エラーが出てしまうので気を付けてください。
逆に created_at だけを無効化するには
updated_atと逆のことをすればいいだけです。
▼ Modelクラスに次のように変更
1 2 3 4 5 6 7 8 9 10 |
class Post extends Model { use HasFactory; /// ▼ これを追加 const CREATED_AT = null; protected $table = 'posts'; public $timestamps = true; } |
まあ単純にこうするだけです。
こんな簡単なことに結構悩んでしまった...
Laravelでtimestampsを無効化する方法のまとめ
端的に箇条書きするとこういう感じ
- migrationファイルにて
テーブル作成時に $table->timestamps(); をコメントアウトするか消しておく。当然これだけだと更新時とかにエラーが出るので要注意!
- Modelクラスにて
もしupdated_atカラムだけを無効化したのなら const UPDATED_AT = null; の記述を追加しておく。逆にcreated_atカラムだけ無効化ということも可能
以上、Laravel Eloquentで timestamps の無効化手順でした。
ではまた(@^^)/~~~