2012-03-20 14 views
14

He creado un modelo con varios campos que deben aceptar el mismo formato de datos (cadenas, pero puede ser cualquier cosa, FWIW). Me gustaría aplicar la misma regla de validación a todos esos campos. Por supuesto, puedo seguir y copiar/pegar cosas, pero eso sería en contra del principio SECO, y el sentido común también ...Rieles 3: aplique las mismas reglas de validación a campos de tabla múltiple

Creo que este es bastante fácil, pero soy un recién llegado/hipster de Rails , entonces excuse-moi para una pregunta trivial. =)

Respuesta

21

Así que si había decir tres campos para validar:

:first_name 
:last_name 
:age 

y que quería que todos sean validados? Así que algo como esto:

validates_presence_of :first_name, :last_name, :age 

Editar: Existen numerosos métodos diferentes de validación en los carriles) y son maravillosamente flexible). Para el formato del campo, puede usar validates_format_of, y luego usar una expresión regular para hacer coincidir. Aquí está un ejemplo de un correo electrónico a juego:

validates_format_of :email, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i 

Me echa un vistazo a la guía Active Record Validations and Callbacks; proporciona información exhaustiva sobre muchas de las funciones que proporciona Active Record en términos de validación. También puede consultar la documentación here.

+0

Sí, pero ¿qué pasa con algo más exótico, como la compatibilidad con expresiones regulares? – aL3xa

+0

Me di cuenta de lo estúpido/simple que era. Lo siento, y gracias! =) – aL3xa

+0

¡Ningún problema! También adelanté y adjunté algunos detalles/recursos. Si ha encontrado esta respuesta como una solución, por favor "aceptarla" haciendo clic en el ícono al lado de mi publicación. Eso indicará que la pregunta está cerrada y que está satisfecho con mi ayuda. ¡La mejor de las suertes con rails de aprendizaje! –

5

Si está usando alguna de las validaciones incorporadas (presencia, length_of) se puede aplicar una única validación de múltiples atributos como esto:

validates_presence_of :name, :email 

Si usted tiene cierta lógica de negocio puede crear un objeto validador para albergar el código y aplicarlo de forma individual

class EmailValidator < ActiveModel::EachValidator 
    def validate_each(record, attribute, value) 
    record.errors[attribute] << (options[:message] || "is not an email") unless 
     value =~ /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i 
    end 
end 

def Person 
    validates :home_email, :email => true 
    validates :work_email, :email => true 
end 

véase: http://thelucid.com/2010/01/08/sexy-validation-in-edge-rails-rails-3/

1

uso Themis para esto:

# Describe common validation in module 
module CommonValidation 
    extend Themis::Validation 

    validates_presence_of :foo 
    validates_length_of :bar, :maximum => 255 
end 

class ModelA < ActiveRecord::Base 
    # import validations 
    include CommonValidation 
end 

class ModelB < ActiveRecord::Base 
    # import validations 
    include CommonValidation 
end 
3

En Rails 4 se puede aplicar la misma validación de varias columnas mediante el uso de un bucle:

[:beds, :baths].each do |column| 
    validates column, allow_blank: true, length: { maximum: 25 } 
end 

Las dos camas y baños son validados utilizando las mismas validaciones.

Editar:

En Rails 4.2 que puede hacer esto mismo, poniendo múltiples símbolos después de la llamada a la función valida. Ejemplo:

validates :beds, :baths, allow_blank: true 
Cuestiones relacionadas