2010-05-13 76 views
24

我知道我可以通過將validates_presence_of :field添加到模型來要求字段。但是,我如何要求至少有一個字段是強制性的,而不需要任何特定字段?Rails:如何要求至少有一個字段不爲空

在此先感謝

- 德布

+1

我認爲你必須寫自己的驗證 – 2010-05-13 00:04:26

回答

24

你可以用途:

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列,這可能不是您想要的。

+8

爲了更新Rails 3的這個答案,使用'errors.add:base,「Error Message」'as add_to_base is deprecated – 2012-02-14 22:42:44

7

添加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 
+0

我相信這是不是很好,如果有很多領域:/ – 2010-05-13 00:30:03

+0

我無法想象他會想檢查一個場_in他的整個model_存在。我認爲這是一組特定的領域。 – 2010-05-13 02:40:27

+0

你的回答也是正確的,所以我投票贊成。但是,我最終使用了Voyta的答案。謝謝回覆! – deb 2010-05-17 21:00:08

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 
1

與@進一步說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"] 
7

這裏有一個可重複使用的版本:

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) 
+0

而不是在這裏將'all?'與'blank?'配對,你也可以將'any?'與'present?',以便代碼本身遵循驗證器名稱的語義 – user456584 2014-11-14 22:08:49

+0

我已根據您的建議更新瞭解決方案。 – 2014-11-16 02:35:59

+0

這顯然是最好的答案! – micapam 2016-09-27 23:20:20

相關問題