2012-03-20 12 views
14

Ho creato un modello con diversi campi che dovrebbero accettare lo stesso formato di dati (stringhe, ma può essere qualsiasi cosa, FWIW). Mi piacerebbe applicare la stessa regola di convalida a tutti quei campi. Certo, posso andare avanti e copiare/incollare roba, ma sarebbe contro il principio ASCIUGATURA, e anche il buon senso ...Rails 3: applica le stesse regole di convalida a più campi di tabella

Immagino che questo sia abbastanza facile, ma io sono un nuovo arrivato Rails/hipster , quindi excuse-moi per una domanda banale. =)

risposta

21

Quindi, se tu avessi detto tre campi per la convalida:

:first_name 
:last_name 
:age 

E si voleva a tutti di essere convalidati? Quindi, qualcosa di simile:

validates_presence_of :first_name, :last_name, :age 

Edit: Ci sono numerosi metodi di validazione diversi in Rails) e sono meravigliosamente flessibile). Per il formato del campo è possibile utilizzare validates_format_of e quindi utilizzare un'espressione regolare per farlo corrispondere. Ecco un esempio di corrispondenza una e-mail:

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

avrei leggi la guida Active Record Validations and Callbacks; fornisce informazioni complete su molte delle funzionalità che Active Record fornisce in termini di convalida. Puoi anche consultare la documentazione here.

+0

Sì, ma che dire di qualcosa di più esotico, come la corrispondenza regex? – aL3xa

+0

Mi sono reso conto di quanto sia stato stupido/semplice. Scusa, e grazie! =) – aL3xa

+0

Nessun problema! Ho anche proseguito e allegato alcuni dettagli/risorse. Se hai trovato questa risposta come soluzione, ti preghiamo di "accettarla" facendo clic sull'icona accanto al mio post. Ciò indica che la domanda è chiusa e sei soddisfatto del mio aiuto. Buona fortuna con le guide di apprendimento! –

5

Se si utilizza una qualsiasi delle convalide built-in (presenza, length_of) è possibile applicare una singola convalida per più attributi in questo modo:

validates_presence_of :name, :email 

Se si dispone di logica personalizzata è possibile creare un oggetto validatore per ospitare il codice e applicarlo individualmente

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 

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

1

Usa Themis per questo:

# 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

In Rails 4 è possibile applicare lo stesso convalida per più colonne utilizzando un ciclo:

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

Entrambi i letti e bagni vengono convalidati utilizzando gli stessi convalide.

Edit:

In Rails 4.2 si può fare la stessa cosa mettendo più simboli dopo la chiamata funzione convalida. Esempio:

validates :beds, :baths, allow_blank: true 
Problemi correlati