自社開発企業での実務を通じて、Railsのモデルファイルでboolean型カラムへのバリデーションのかけ方を学んだので、備忘録としてまとめます。
記事の前半ではboolean型カラムへのバリデーションにinclusion を使うべき理由を、後半ではboolean型カラムのバリデーションにpresence がNGな理由を解説します。
最後まで読めば、Railsにおいてboolean型カラムへ適切なバリデーションをかけられるようになるはずです。
boolean型カラムのバリデーションにはinclusionを使う
Railsのモデルファイル内で、boolean型カラムにバリデーションをかける際は、presenceではなくinclusionをつかいます。
たとえば以下のとおり。
Userモデルの例(超シンプル)
class User < ApplicationRecord
  validates :name, presence: true
  validates :email, presence: true, uniqueness: true
  validates :is_active, inclusion: [true, false]
endinclusionをつかうことで、is_activeカラムに格納される値はtrue, falseのどちらかとなります。
もしくは、次のようにexclusionをつかってnilを回避する書き方でもOKです。
class User < ApplicationRecord
  validates :name, presence: true
  validates :email, presence: true, uniqueness: true
  validates :is_active, exclusion: [nil]
end
boolean型カラムのバリデーションにpresenceがNGな理由
結論として、falseが格納できなくなってしまうから。
じつはpresenceは内部的にblank?メソッドで値の存在を判定していまして、これが問題をひきおこします。
Userモデルの例で考える
仮に、user.rbが次のようになっていたとします。
class User < ApplicationRecord
  validates :name, presence: true
  validates :email, presence: true, uniqueness: true
  validates :is_active, presence: true
endもし、is_activeカラムにtrueが指定された場合はtrue.blank?、falseが指定された場合はfalse.blank?で、値の存在がチェックされます。
しかし、Rubyではfalseは偽とあつかうため、false.blank?はtrueと判定されてしまうのです。
Railsコンソールで試してみた
[1] pry(main)> true.blank?
=> false
[2] pry(main)> false.blank?
=> trueつまり、is_activeカラムにfalseを格納しようとしても、「値が存在しない」とみなされ、エラーが発生します。
だから、 boolean型カラムにはpresence: trueではなく、inclusionもしくはexclusionをつかうべきなんですね。
まとめ
boolean型カラムには、presenceではなく、inclusionでバリデーションをかけるべきと学びました。
			
			
			
			
コメント