Ruby-on-rails 验证:如果
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8533891/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Validates with :if
提问by James
I'm trying to create a condition in which the attribute 'one' is zero and the attribute 'two' is one, then a model is not valid. But when I make:
我正在尝试创建一个条件,其中属性“一”为零且属性“二”为一,则模型无效。但是当我做:
Model.create(:one => 1, :two => 0).valid?
The unit test returns true! Why?
单元测试返回true!为什么?
validates :one, :two, :presence => true, :if => :if condition_testing?
def condition_testing?
!(one == 0 && two == 1)
end
回答by Tigraine
I think you have an error in your syntax:
我认为您的语法有误:
validates :one, :two, :presence => true, :if => :condition_testing?
def condition_testing?
!(one == 0 && two == 1)
end
There was one :if too many in there...
And if I understand correctly you want to have it only validate in case one == 0 && two == 1?
Then you condition_testing? is inverted (leave out the !())
有一个:如果那里有太多...如果我理解正确,您只想让它验证以防万一one == 0 && two == 1?那你condition_testing?被倒置(省略!())
If unsure you could try to use pryand insert a breakpoint into your condition_testing?method to see what's going on.
如果不确定,您可以尝试使用pry并在您的condition_testing?方法中插入断点以查看发生了什么。
(Please note added ":" before condition testing)
(请注意在条件测试前添加“:”)
回答by potashin
You can validate it in one line:
您可以在一行中验证它:
validates :one, :two, :presence => true, :if => Proc.new { |a| !(a.one == 0 && a.two == 1) }
回答by psulightning
You are better off using numericality and equal to.
你最好使用数值和等于。
validates :one, :numericality => { :equal_to => 0 }
validates :two, :numericality => { :equal_to => 1 }
http://guides.rubyonrails.org/active_record_validations_callbacks.html#numericality
http://guides.rubyonrails.org/active_record_validations_callbacks.html#numericality
回答by Logan Leger
The problem is that you're using a presence validator with a condition that checks the values of the attributes. This is incorrect. A presence validator checks to make sure those attributes are set. What's worse, you're passing the ifoption (@Tigraine was correct about your syntax being wrong, by the way), which means whenever that method returns true, the presence won't be checked at all. The way you have this set up, the validator will run only when oneis equal to 1 and twois equal to 0. Otherwise, no validations are run at all! I think the best option here is to write a custom validation:
问题是您正在使用具有检查属性值的条件的存在验证器。这是不正确的。存在验证器检查以确保设置了这些属性。更糟糕的是,您正在传递该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
This will add an error to the model with the specified message if the condition returns true. (Note: I'm still not clear on what condition is valid and which is invalid, so feel free to change that last part to suit your needs.)
如果条件返回 true,这将使用指定的消息向模型添加错误。(注意:我仍然不清楚哪些条件有效,哪些条件无效,因此请随时更改最后一部分以满足您的需要。)

