自社開発企業での実務を通じて、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]
end
inclusion
をつかうことで、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
でバリデーションをかけるべきと学びました。
コメント