web-dev-qa-db-ja.com

:ifで検証します

属性「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
12
James

構文にエラーがあると思います:

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?メソッドにブレークポイントを挿入し、何が起こっているかを確認します。

(条件テストの前に「:」が追加されていることに注意してください)

18
Tigraine

1行で検証できます。

validates :one, :two, :presence => true, :if => Proc.new { |a| !(a.one == 0 && a.two == 1) }
11
potashin

数値を使用して等しいことをお勧めします。

validates :one, :numericality => { :equal_to => 0 }

validates :two, :numericality => { :equal_to => 1 }

http://guides.rubyonrails.org/active_record_validations_callbacks.html#numericality

4
psulightning

問題は、属性の値をチェックする条件でプレゼンスバリデーターを使用していることです。これは誤りです。プレゼンスバリデーターは、これらの属性が設定されていることを確認します。さらに悪いことに、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を返した場合、指定されたメッセージとともにモデルにエラーが追加されます。 (注:有効な条件と無効な条件についてはまだ明確ではないため、最後の部分をニーズに合わせて自由に変更してください。)

3
Logan Leger