【问题标题】:Rails: how to require at least one field not to be blankRails:如何要求至少一个字段不为空
【发布时间】:2011-02-18 21:35:11
【问题描述】:

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

提前致谢

-- 德布

【问题讨论】:

  • 我相信你必须自己写验证

标签: ruby-on-rails validation models


【解决方案1】:

为您的模型添加一个validate 方法:

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

【讨论】:

  • 我无法想象他会想要检查在他的整个模型中是否存在一个字段。我认为这是一组特定的字段。
  • 你的答案也是正确的,所以我也投了赞成票。但是,我最终使用了 Voyta 的答案。感谢您的回复!
  • @RobertSpeicher 我同意你的看法,因为通常情况下,我们想检查两者中的一个是否存在。例如:(电话或电子邮件)或(截止日期或拖欠日期)不只需要 10 个字段中的一个或......所以,我投票赞成你的答案,因为它很简单。
【解决方案2】:

我相信像下面这样的东西可能会起作用

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

【讨论】:

    【解决方案3】:

    你可以使用:

    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_columns.map(&amp;:name) 获取模型的所有内容列,但它也将包括created_atupdated_at 列,这可能不是您想要的。

    【讨论】:

    • 要更新 Rails 3 的这个答案,请使用 errors.add :base, "Error Message",因为 add_to_base 已弃用
    【解决方案4】:

    进一步了解@Votya 的正确答案,这是一种检索除 created_at 和 updated_at 之外的所有列(以及您想要丢弃的任何其他列)的方法:

    # Get all column names as an array and reject the ones we don't want
    Model.content_columns.map(&:name).reject {|i| i =~ /(created|updated)_at/}
    

    例如:

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

    【讨论】:

      【解决方案5】:

      这是一个可重复使用的版本:

      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)
      

      【讨论】:

      • 这里不是将all?blank? 配对,您还可以将any?present? 配对,以便代码本身遵循验证器名称的语义
      猜你喜欢
      • 1970-01-01
      • 2020-03-08
      • 2011-07-21
      • 2016-06-29
      • 2021-02-23
      • 2019-11-11
      • 2011-06-25
      • 2015-08-12
      • 1970-01-01
      相关资源
      最近更新 更多