2010-05-13 10 views

Odpowiedz

24

Można użyj:

validate :any_present? 

def any_present? 
    if %w(field1 field2 field3).all?{|attr| self[attr].blank?} 
    errors.add :base, "Error message" 
    end 
end 

EDYCJA: zaktualizowano z oryginalnej odpowiedzi dla Rails 3+ zgodnie z komentarzem.

Musisz jednak podać nazwy pól ręcznie. Można uzyskać wszystkie kolumny zawartości modelu z Model.content_columns.map(&:name), ale będą również zawierać kolumny created_at i updated_at, a to prawdopodobnie nie jest to, co chcesz.

+8

Aby zaktualizować tę odpowiedź dla Rails 3, użyj 'errors.add: base," Komunikat o błędzie "' as add_to_base jest przestarzałe –

7

Dodaj metodę validate do modelu:

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

Uważam, że nie jest bardzo dobra, jeśli istnieje wiele pól:/ –

+0

Nie mogę sobie wyobrazić, że chciał sprawdzić, czy jedno pole _in całym swoim model_ jest obecny. Zakładałem, że był to konkretny zestaw pól. –

+0

twoja odpowiedź jest również poprawna, więc również głosowałem za nią. Jednak skończyłem używając odpowiedzi Voyta. Dziękuję za odpowiedź! – deb

2

wierzę, coś jak poniżej może pracować

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

Idąc dalej z @ poprawną odpowiedź Votya, oto jest sposób, aby odzyskać wszystkie kolumny oprócz created_at i updated_at (i ewentualnie jakieś inne chcesz wyrzucić):

# 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/} 

Na przykład:

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

Oto wielokrotnego użytku wersja:

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

można go używać w swoim modelu:

validates_with AnyPresenceValidator, fields: %w(field1 field2 field3) 
+0

Zamiast parowania 'all?' Z 'pustym?' Tutaj, możesz również sparować 'any?' Z 'present?', aby kod sam podążał za semantyką nazwy weryfikatora – user456584

+0

Zaktualizowałem rozwiązanie zgodnie z twoją sugestią. –

+0

To zdecydowanie najlepsza odpowiedź! – micapam