LoginSignup
51
33

More than 3 years have passed since last update.

カラムのNot Null制約を外すには引数にnull: trueを指定しないとダメ

Last updated at Posted at 2018-06-07

結論

NN制約のないカラムにNN制約をかけるときはmigrationのdownメソッドにnull: trueと書く必要はないが、NN制約を外す場合はmigrationのupメソッドにnull: trueを明示しなければならない。

カラムにNN制約をかけたい

$ bin/rails g migration ChangeColumnToNotNull
db/migrate/2018xxxxxxxxxx_change_column_to_not_null.rb
class ChangeColumnToNotNull < ActiveRecord::Migration[5.1]
  def up
    change_column :users, :name,:string, null: false
  end

  def down
    change_column :users, :name,:string
  end
end

null: trueと書く必要はありません。

カラムにかけたNN制約を外したいとき

$ bin/rails g migration ChangeColumnToAllowNull
db/migrate/2018xxxxxxxxxx_change_column_to_allow_null_.rb
class changeColumnToAllowNull < ActiveRecord::Migration[5.1]
  def up
    change_column :users, :name,:string, null: true # null: trueを明示する必要がある
  end

  def down
    change_column :users, :name,:string, null: false
  end
end

null: trueと書く必要があります。

理由

Railsでは、カラムのデフォルトはnull: true(NN制約なし)です。
このため、NN制約をかける際にmigrationのdownメソッドにnull: true と書く必要はありません(デフォルト値が入る)。

しかし、いったんnull: falseにしたあとnull: trueにしたいときは明示する必要があります。

ActiveRecordの下記の実装がヒントでした。

rails/activerecord/lib/active_record/migration/command_recorder.rb
196        def invert_change_column_null(args)
197          args[2] = !args[2]
198          [:change_column_null, args]
199        end

2番目の引数がtrueだったらfalseに、falseだったらtrueにするので、引数にnull: trueまたはnull: falseを指定する必要があります。

51
33
4

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
51
33