仅当virt_attribute为false时才validation字段

我有这样的模特:

class Order  {:message => I18n.t(:city_not_chosen)} validates :zip, :presence => {:message => I18n.t(:zip_not_chosen)} validates :street, :presence => {:message => I18n.t(:street__not_chosen)} validates :building, :presence => {:message => I18n.t(:building_not_chosen)} validates :phone_number, :presence => {:message => I18n.t(:phone_number_not_chosen)} validates :receiver, :presence => {:message => I18n.t(:receiver_not_chosen)} end 

正如你所看到的,我在模型中设置了一些非db字段(use_user_data) – 虚拟属性…

但是怎么做,如果:use_user_data是假的,好的和正确的validation,但是当真的没有validation?

我试试这样:

 validates :city, :presence => {:message => I18n.t(:city_not_chosen)}, :unless => :use_user_data 

所以

 with_options :unless => :use_user_data do |order| order.validates :city, :presence => {:message => I18n.t(:city_not_chosen)} end 

但它对我没有帮助……为什么?

我的表格也是:

 = form_for @order do |f| %div = f.label :use_user_data , "Использовать данные вашего профиля*: " = label :use_user_data , "Да" = f.radio_button :use_user_data, true, :required => true, :id => "use_user_data", :checked => true = label :use_user_data , "Нет" = f.radio_button :use_user_data, false, :required => true, :id => "dont_use_user_data" 

当我写的时候

 validates :city, :presence => {:message => I18n.t(:city_not_chosen)}, :if => :use_user_data 

我得到validation消息……但是只有在假的时候怎么做? 为什么我的解决方案不起作用?

表单将“true”或“false”字符串传递给对象,而不是布尔值truefalse 。 由于它是虚拟属性,因此不执行类型转换。 在Ruby中,“true”和“false”都是true ,因此您需要使用某些东西来对类值进行类型转换

 with_options :unless => Proc.new{ |a| a.use_user_data == 'true' } do |order| order.validates ... end 

要么

 with_options :unless => :use_user_data? do |order| order.validates ... end def use_user_data? use_user_data == 'true' end 

你需要把你的:if:unless条件放在lambda或Proc

 validates ..., :if => Proc.new { |a| a.use_user_data === false } 

这导致检查:use_user_data在validation期间执行上述validates行之前不会被评估Proc作为值传递给:if:unless选项由Rails评估)Proc将接收当前模型属性作为参数,允许您检查这些属性(在这种情况下, :use_user_datafalse