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

vlurs2pr  于 2022-12-05  发布在  Ruby
关注(0)|答案(6)|浏览(87)

我知道我可以通过向模型中添加validates_presence_of :field来要求一个字段。但是,我如何要求至少一个字段是必填的,而不要求任何特定的字段呢?
先谢了
--黛布

mwkjh3gx

mwkjh3gx1#

您可以用途:

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

ff29svar

ff29svar2#

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

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)
hsgswve4

hsgswve43#

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
r7knjye2

r7knjye24#

我认为以下方法可能有效

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
bogh5gae

bogh5gae5#

下面是@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"]
1wnzp6jl

1wnzp6jl6#

如果您只有两个字段,这将完成工作:

validates :first_name, presence: true, if: :nick_name.blank?
validates :nick_name, presence: true, if: :first_name.blank?

这对于更多的字段来说不能很好地扩展,但是当您只有两个字段时,这可能比自定义验证方法更清楚。
注意:如果它们都省略了,错误信息会比你想要的更严格。(例如First Name is required. Nick Name is required.)¯*()*/¯

相关问题