7
5

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 3 years have passed since last update.

#Rails + MySQL で timestamps のマイグレーションを忘れていたので後から created_at / updated_at カラムを追加する

7
Last updated at Posted at 2019-12-29

points

  • null を許可してカラムを追加する。
  • 全てのレコードに値を入れる。
  • null を不許可に変える。

warning

カラム1個を追加する場合は timestams でもなく timestamp でもなくて datetime を指定することに注意。

( あなたの Rails の t.timestamps は datetime 型のカラムを MySQL に追加しているか? 環境によるかもしれない。確認してほしい )

migration

class AddCreatedAtToUser < ActiveRecord::Migration[5.2]
  def up
    add_column :users, :created_at, :datetime, null: true

    User.update_all(created_at: Time.current)

    change_column :users, :created_at, :datetime, null: false
  end

  def down
    remove_column :users, :created_at
  end
end

既存レコードを作った上で

bundle exec rails db:migrate
bundle exec rails db:rollback

などを実行して試してみよう。

null を許可せずにカラム追加した場合

null を許可しない場合、既存レコードがあるとエラーでmigrationがキャンセルされてしまう。

class AddCreatedAtToUser < ActiveRecord::Migration[5.2]
  def change
    add_column :users, :created_at, :datetime, null: false
  end
end
StandardError: An error has occurred, all later migrations canceled:

Mysql2::Error: Incorrect datetime value: '0000-00-00 00:00:00' for column 'created_at' at row 1: ALTER TABLE `users` ADD `created_at` datetime NOT NULL

...

Caused by:
ActiveRecord::StatementInvalid: Mysql2::Error: Incorrect datetime value: '0000-00-00 00:00:00' for column 'created_at' at row 1: ALTER TABLE `users` ADD `created_at` datetime NOT NULL

デフォルトを指定した場合

class AddCreatedAtToUser < ActiveRecord::Migration[5.2]
  def change
    add_column :users, :created_at, :datetime, null: false, default: -> { 'NOW()' }
  end
end

migrationは出来るがカラムに default値が設定されてしまい、 テーブル作成時に t.timestamps を指定した状態とは違ってしまう。

  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,

デフォルト値を指定し、後から削除しようとした場合

サーバー設定のせいかうまく行かなかった。

class AddCreatedAtToUser < ActiveRecord::Migration[5.2]
  def change
    add_column :users, :created_at, :datetime, null: false, default: -> { 'NOW()' }
    change_column :users, :created_at, :datetime, null: false, default: ''
  end
end
rails aborted!
StandardError: An error has occurred, all later migrations canceled:

Mysql2::Error: Invalid default value for 'created_at': ALTER TABLE `users` CHANGE `created_at` `created_at` datetime DEFAULT NULL NOT NULL
...

Caused by:
ActiveRecord::StatementInvalid: Mysql2::Error: Invalid default value for 'created_at': ALTER TABLE `users` CHANGE `created_at` `created_at` datetime DEFAULT NULL NOT NULL

Ref

mysqlにカラムを追加しようとしたらInvalid default value for エラー - Qiita
https://qiita.com/rh_/items/be798e69a8f9000c56b1

Setting MySQL DATETIME column defaults in Rails
https://www.mikeperham.com/2014/05/17/setting-mysql-datetime-column-defaults-in-rails/

Original by Github issue

チャットメンバー募集

何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

Twitter

7
5
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
7
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?