2012-01-16 20 views
23

Sto usando Rails v2.3saltare certo metodo di convalida nel Modello

Se ho un modello :

class car < ActiveRecord::Base 

    validate :method_1, :method_2, :method_3 

    ... 
    # custom validation methods 
    def method_1 
    ... 
    end 

    def method_2 
    ... 
    end 

    def method_3 
    ... 
    end 
end 

Come vedete sopra, ho metodi di validazione personalizzati 3 e li uso per la convalida del modello.

Se ho un altro metodo in questa classe del modello che salvare una nuova istanza del modello come segue:

# "flag" here is NOT a DB based attribute 
def save_special_car flag 
    new_car=Car.new(...) 

    new_car.save #how to skip validation method_2 if flag==true 
end 

Vorrei saltare la validazione di method_2 in questo particolare metodo per il salvataggio di nuova auto, come saltare il metodo di convalida certo?

+0

La tua "macchina speciale" ha qualche attributo che può differenziarlo dalle auto non speciali? Ciò renderebbe questo semplice. – Dogbert

+1

Hai esaminato i documenti [convalida condizionale] (http://guides.rubyonrails.org/active_record_validations_callbacks.html#conditional-validation)? –

+0

Ciao, ho aggiornato il mio post per il metodo di salvataggio di un'auto speciale. Fondamentalmente, ho un parametro "flag" passare al metodo, e se "flag" è vero, vorrei saltare la convalida di method_2 –

risposta

46

Aggiornare il modello per questo

class Car < ActiveRecord::Base 

    # depending on how you deal with mass-assignment 
    # protection in newer Rails versions, 
    # you might want to uncomment this line 
    # 
    # attr_accessible :skip_method_2 

    attr_accessor :skip_method_2 

    validate :method_1, :method_3 
    validate :method_2, unless: :skip_method_2 

    private # encapsulation is cool, so we are cool 

    # custom validation methods 
    def method_1 
     # ... 
    end 

    def method_2 
     # ... 
    end 

    def method_3 
     # ... 
    end 
end 

Poi nel controller messo:

def save_special_car 
    new_car=Car.new(skip_method_2: true) 
    new_car.save 
end 

Se stai ricevendo :flag tramite variabile params nel controller, è possibile utilizzare

def save_special_car 
    new_car=Car.new(skip_method_2: params[:flag].present?) 
    new_car.save 
end 
+0

Che 'attr_writer' dovrebbe essere' attr_accessor' o otterrai un ' errore locale non definito o metodo "skip_method". Oppure potresti scrivere la tua funzione di lettore come "skip_method?". – Ashitaka

+0

@Ashitaka aggiornato, grazie! – shime

+0

Grazie per questa risposta. Ho cercato molto per questo.Per chiunque altro possa capitarmi, penso che otterrai un errore di MassAssignment se lo fai in questo modo. Puoi evitare l'errore facendo così: 'new_car = Car.new',' new_car.skip_method_2 = params [: flag] .present? ' – lnreddy

11

L'uso di base della convalida condizionale è:

class Car < ActiveRecord::Base 

    validate :method_1 
    validate :method_2, :if => :perform_validation? 
    validate :method_3, :unless => :skip_validation? 

    def perform_validation? 
    # check some condition 
    end 

    def skip_validation? 
    # check some condition 
    end 

    # ... actual validation methods omitted 
end 

Partenza la documentazione per ulteriori dettagli.

Regolazione al vostro screnario:

class Car < ActiveRecord::Base 

    validate :method_1, :method_3 
    validate :method_2, :unless => :flag? 

    attr_accessor :flag 

    def flag? 
    @flag 
    end  

    # ... actual validation methods omitted 
end 

car = Car.new(...) 
car.flag = true 
car.save 
+0

In realtà, flag non è un attributo basato su DB ... Quindi ... in un altro modo? –

+0

Vedere la risposta aggiornata che utilizza quindi attibute non basati su db. –

-1

A seconda delle condizioni atmosferiche flag è vero o falso, utilizzare il metodo save(false) di saltare la convalida.

+3

'save (false)' salterà l'intera convalida, non solo un metodo. – shime

+0

Inoltre è 'save (validate: false)', non 'save (false)' – Fritzz

+0

è 'save (false)' in Rails v2.3 – daslicious

0

Utilizzare il blocco nella convalida come:

validates_presence_of :your_field, :if => lambda{|e| e.your_flag ...your condition} 
Problemi correlati