【Rails】boolean型カラムのバリデーションにはinclusionを使う【presenceはNG】

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

参考文献
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

未経験でSESから従業員300名以上の自社開発企業に転職しました。業務や個人開発で直面した問題や、転職・学習の経験を発信していきます。

コメント

コメントする

目次