2009-12-02 15 views
6

? Estoy respondiendo mis propias preguntas, simplemente poniéndolo aquí para google-fu en caso de que ayude a alguien más. Este código le permite validar la presencia de un campo en una lista. Ver los comentarios en el código para el uso. Sólo pega esto en lib/custom_validations.rb y añadir requerir '' custom_validations a su environment.rb¿Cómo se valida la presencia de un campo entre muchos

#good post on how to do stuff like this http://www.marklunds.com/articles/one/312 

module ActiveRecord 
    module Validations 
    module ClassMethods 

     # Use to check for this, that or those was entered... example: 
     # :validates_presence_of_at_least_one_field :last_name, :company_name - would require either last_name or company_name to be filled in 
     # also works with arrays 
     # :validates_presence_of_at_least_one_field :email, [:name, :address, :city, :state] - would require email or a mailing type address 
     def validates_presence_of_at_least_one_field(*attr_names) 
     msg = attr_names.collect {|a| a.is_a?(Array) ? " (#{a.join(", ")}) " : a.to_s}.join(", ") + 
        "can't all be blank. At least one field (set) must be filled in." 
     configuration = { 
      :on => :save, 
      :message => msg } 
     configuration.update(attr_names.extract_options!) 

     send(validation_method(configuration[:on]), configuration) do |record| 
      found = false 
      attr_names.each do |a| 
      a = [a] unless a.is_a?(Array) 
      found = true 
      a.each do |attr| 
       value = record.respond_to?(attr.to_s) ? record.send(attr.to_s) : record[attr.to_s] 
       found = !value.blank? 
      end 
      break if found 
      end 
      record.errors.add_to_base(configuration[:message]) unless found 
     end 
     end 

    end 
    end 
end 

Respuesta

14

Esto funciona para mí en los carriles 3, aunque sólo estoy validando si uno o el otro campo está presente:

validates :last_name, :presence => {unless => Proc.new { |a| a.company_name.present? }, :message => "You must enter a last name, company name, or both"} 

Eso solo validará la presencia de last_name si el nombre de la compañía está en blanco. Solo necesita uno porque ambos estarán en blanco en la condición de error, por lo que tener un validador también en el nombre de compañía es redundante. Lo único molesto es que escupe el nombre de la columna antes del mensaje, y utilicé la respuesta de this pregunta sobre Atributos humanizados para evitarlo (simplemente estableciendo el último atributo humanizado de ""

+5

': unless => ' company_name'' es verdadero solo si company_name es nil, no es la cadena vacía. 'unless => Proc.new {| a | a.company_name.present?}' también buscará la cadena vacía. –

Cuestiones relacionadas