Ruby on rails Rails:如何要求至少一个字段不为空

Ruby on rails Rails:如何要求至少一个字段不为空,ruby-on-rails,validation,models,Ruby On Rails,Validation,Models,我知道我可以通过向模型中添加来验证:field的存在,从而需要一个字段。但是,如何要求至少有一个字段是必填字段,而不要求任何特定字段 提前谢谢 --Deb将验证方法添加到模型中: def validate if field1.blank? and field2.blank? and field3.blank? # ... errors.add_to_base("You must fill in at least one field") end end 我相信下面的方法可能会奏效

我知道我可以通过向模型中添加
来验证:field
的存在,从而需要一个字段。但是,如何要求至少有一个字段是必填字段,而不要求任何特定字段

提前谢谢


--Deb

验证方法添加到模型中:

def validate
  if field1.blank? and field2.blank? and field3.blank? # ...
    errors.add_to_base("You must fill in at least one field")
  end
end

我相信下面的方法可能会奏效

class MyModel < ActiveRecord::Base
   validate do |my_model|
      my_model.my_validation
   end

   def my_validation      
      errors.add_to_base("Your error message") if self.blank? 
      #or self.attributes.blank? - not sure
   end
end
classmymodel
您可以使用:

validate :any_present?

def any_present?
  if %w(field1 field2 field3).all?{|attr| self[attr].blank?}
    errors.add :base, "Error message"
  end
end
编辑:根据评论更新Rails 3+的原始答案

但是您必须手动提供字段名。
您可以使用
model.content\u columns.map(&:name)
获得模型的所有内容列,但它也将包括
created\u at
updated\u at
列,这可能不是您想要的。

进一步了解@Votya的正确答案,这里有一种方法可以检索除created\u at和updated\u at之外的所有列(或者,您想扔掉的任何其他垃圾):

例如:

 1.9.3p327 :012 > Client.content_columns.map(&:name).reject {|i| i =~ /(created|updated)_at/}
 => ["primary_email", "name"]

这是一个可重用的版本:

class AnyPresenceValidator < ActiveModel::Validator
  def validate(record)
    unless options[:fields].any?{|attr| record[attr].present?}
      record.errors.add(:base, :blank)
    end
  end
end

我相信你必须自己编写验证。我无法想象他会想检查整个模型中是否存在一个字段。我假设它是一组特定的字段。你的答案也是正确的,所以我也投票了。但是,我最终使用了Voyta的答案。谢谢你的回答!@RobertSpeicher我同意你的看法,因为通常情况下,we想检查两个字段中是否有一个存在。例如:(电话或电子邮件)或(截止日期或延迟日期)不要求10个字段中只有一个字段,或者……因此,我投票支持您的答案,因为它简单。要更新Rails 3的此答案,请使用
errors.add:base,“Error Message”
由于不推荐将
all?
blank?
配对,因此您也可以将
any?
present?
配对,以便代码本身遵循验证程序名称的语义
class AnyPresenceValidator < ActiveModel::Validator
  def validate(record)
    unless options[:fields].any?{|attr| record[attr].present?}
      record.errors.add(:base, :blank)
    end
  end
end
validates_with AnyPresenceValidator, fields: %w(field1 field2 field3)