LoginSignup
0
0

More than 1 year has passed since last update.

migrationのrollbackの注意点(dafault値の取り扱い)

Last updated at Posted at 2021-12-20

TL;DR

migrate後のmigrationファイルを書き換えると、データの値が荒れがち。
rubocopに「直したほうが良い」と言われようとも、migrationファイルは書き換えないのが基本。
(自戒の念を込めて記事化)

状況

rubocopで静的解析をかけた時のお話。
こんな表示が出ました。

rubocop実行画面
db/migrate/20210827131348_add_activations_to_users.rb:9:5: 
C: Rails/BulkChangeTable: 
You can use change_table :relationships, bulk: true to combine alter queries.

「add_columnを何度も重ねずに、add_tableで一括変更してくれ」とのことなので、
そのように変更。

やったこと

"rails db:migrate:status" => ID確認。
"rails db:migrate:down VERSION=xxxxxxx" => downに

その後、migrationファイルを変更してmigrate実行

migrationファイル
class AddActivationToUsers < ActiveRecord::Migration[6.1]
  def change
    add_column :users, :activation_digest, :string
    add_column :users, :activated, :boolean, default: false
    add_column :users, :activated_at, :datetime
  end
end



class AddActivationToUsers < ActiveRecord::Migration[6.1]
  def change
    change_table :users, bulk: true do |t|
      t.string :activation_digest
      t.boolean :activated, default: false
      t.datetime :activated_at
    end
  end
end

結果

既に開発環境で存在しているuserのdefault値が変化。
default値は新規作成の時だけ効果発揮するのだと思ってたけど、違うのね…。

console
[1] pry(main)> User.find(1)
  User Load (0.9ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
=> #<User:0x000055d27e9d5548
 id: 1,
 name: "正太郎",
…
 activated: false,   # migration前はactivated: trueだった

このままデプロイすると、本番環境のデータベースに格納されている値も変化してしまって、非常によろしくない。。

改善

  • migrationによってでデータベースに格納されている値を変えてしまうのはよろしくない。
    基本的にはmigrationファイルの書き換えはしない。
    DBの変更するときはremove_columnとか、change_defaultとか、変更履歴がわかるものにとどめるのが無難だと推察される。

  • rubocop.ymlは以下の通りに変更

rubocop.yml
  Exclude:
    - 'db/**/*'
  • そもそも、本番環境に関しては定期的にバックアップをとりましょう。
0
0
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
0
0