我知道我可以通過將validates_presence_of :field
添加到模型來要求字段。但是,我如何要求至少有一個字段是強制性的,而不需要任何特定字段?Rails:如何要求至少有一個字段不爲空
在此先感謝
- 德布
我知道我可以通過將validates_presence_of :field
添加到模型來要求字段。但是,我如何要求至少有一個字段是強制性的,而不需要任何特定字段?Rails:如何要求至少有一個字段不爲空
在此先感謝
- 德布
你可以用途:
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_at
和updated_at
列,這可能不是您想要的。
爲了更新Rails 3的這個答案,使用'errors.add:base,「Error Message」'as add_to_base is deprecated – 2012-02-14 22:42:44
添加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
我相信這是不是很好,如果有很多領域:/ – 2010-05-13 00:30:03
我無法想象他會想檢查一個場_in他的整個model_存在。我認爲這是一組特定的領域。 – 2010-05-13 02:40:27
你的回答也是正確的,所以我投票贊成。但是,我最終使用了Voyta的答案。謝謝回覆! – deb 2010-05-17 21:00:08
我相信像下面這樣可能工作
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
與@進一步說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"]
這裏有一個可重複使用的版本:
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?',以便代碼本身遵循驗證器名稱的語義 – user456584 2014-11-14 22:08:49
我已根據您的建議更新瞭解決方案。 – 2014-11-16 02:35:59
這顯然是最好的答案! – micapam 2016-09-27 23:20:20
我認爲你必須寫自己的驗證 – 2010-05-13 00:04:26