属性「1」がゼロで属性「2」が1である条件を作成しようとすると、モデルが無効になります。しかし、私が作るとき:
Model.create(:one => 1, :two => 0).valid?
ユニットテストはtrue
を返します!どうして?
validates :one, :two, :presence => true, :if => :if condition_testing?
def condition_testing?
!(one == 0 && two == 1)
end
構文にエラーがあると思います:
validates :one, :two, :presence => true, :if => :condition_testing?
def condition_testing?
!(one == 0 && two == 1)
end
そこには:ifが多すぎます...そして私が正しく理解していれば、ケースone == 0 && two == 1
の場合にのみ検証するようにしたいですか?次に、condition_testing?反転されます(!()を省略します)
不明な場合は、 pry を使用してcondition_testing?
メソッドにブレークポイントを挿入し、何が起こっているかを確認します。
(条件テストの前に「:」が追加されていることに注意してください)
1行で検証できます。
validates :one, :two, :presence => true, :if => Proc.new { |a| !(a.one == 0 && a.two == 1) }
数値を使用して等しいことをお勧めします。
validates :one, :numericality => { :equal_to => 0 }
validates :two, :numericality => { :equal_to => 1 }
http://guides.rubyonrails.org/active_record_validations_callbacks.html#numericality
問題は、属性の値をチェックする条件でプレゼンスバリデーターを使用していることです。これは誤りです。プレゼンスバリデーターは、これらの属性が設定されていることを確認します。さらに悪いことに、if
オプションを渡しています(@Tigraineは構文が間違っていることについては正解でした)。つまり、そのメソッドがtrueを返すときは常に、存在はまったくチェックされません。この設定方法では、バリデーターはone
が1に等しく、two
が0に等しい場合にのみ実行されます。それ以外の場合、検証はまったく実行されません。ここでの最良のオプションは、カスタム検証を作成することだと思います。
validates :one_and_two
def one_and_two
errors.add(:base, "one must be 1 and two must be 0") if !(one == 0 && two == 1)
end
これにより、条件がtrueを返した場合、指定されたメッセージとともにモデルにエラーが追加されます。 (注:有効な条件と無効な条件についてはまだ明確ではないため、最後の部分をニーズに合わせて自由に変更してください。)