🚨

Railsでboolean型のカラムに対して必須バリデーションをつけてみよう

に公開

ゴール

Railsのmodelでboolean型のカラムに対して必須バリデーションをつける。

問題

以下のようにboolean型のカラムis_testに対してpresence: trueバリデーションを使うと、is_testの値がnilの時だけでなく、値がfalseの時にもバリデーションエラーになってしまう。

実装例

class TestModel < ApplicationRecord
  validates :is_test, presence: true
end

上記のmodelに対して、以下のようにレコード作成を試みる。

TestModel.create! is_test: false

すると、以下のように空判定されてバリデーションエラーが発生する。

Validation failed: Has reconcile error can't be blank, Is accepted can't be blank (ActiveRecord::RecordInvalid)

これは、Rails内部はpresenceバリデーションをblank?を使って判定しており、Railsではfalse.blank?がtrue判定になってしまうため。
https://github.com/rails/rails/blob/main/activemodel/lib/active_model/validations/presence.rb#L5-L9

irb(main):001> false.blank?
=> true

対処法

inclusionを使用してtrue, falseのみ値が設定できるようにする。
こうすることでnil許容せずに、値がfalseの時にはエラーがでないように実装できる。

class TestModel < ApplicationRecord
  validates :is_test, inclusion: { in: [true, false] }
end

Discussion