2012-01-16 10 views
23

estoy usando rieles v2.3omitir cierta método de validación en el Modelo

Si tengo un modelo :

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 

Como se ve arriba, tengo métodos de validación personalizados 3 , y los uso para la validación del modelo.

Si tengo otro método en esta clase modelo que guardar una nueva instancia de la modelo como el siguiente:

# "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 

me gustaría omitir la validación de method_2 en este método particular para guardar nuevo coche, cómo saltear el cierto método de validación?

+0

¿Su "automóvil especial" tiene algún atributo que lo diferencie de los automóviles no especiales? Eso haría que esto sea simple. – Dogbert

+1

¿Ha revisado los documentos de validación [condicional] (http://guides.rubyonrails.org/active_record_validations_callbacks.html#conditional-validation)? –

+0

Hola, actualicé mi publicación sobre el método para guardar un automóvil especial. Básicamente, tengo un paso de parámetro de "bandera" para el método, y si "flag" es verdadero, me gustaría omitir la validación de method_2 –

Respuesta

46

actualización de su modelo a este

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 

Luego, en su controlador pone:

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

Si usted está recibiendo :flag, mediante la variación params en tu controlador, puede utilizar

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

Que 'attr_writer' debe ser' attr_accessor' o obtendrás ' variable local indefinida o método 'skip_method'' error. O podría escribir su propia función de lector como 'skip_method?'. – Ashitaka

+0

@Ashitaka actualizado, gracias! – shime

+0

Gracias por esta respuesta. Busqué mucho para esto.Para cualquier otra persona que se encuentre con esto, creo que obtendrá un error de MassAssignment si lo hace así. Puede evitar el error haciendo lo siguiente: 'new_car = Car.new',' new_car.skip_method_2 = params [: flag] .present? ' – lnreddy

11

El uso básico de la validación condicional es:

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 

Mira la documentación para más detalles.

Ajuste a su 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

En realidad, la bandera no es un atributo basado en DB ... Entonces ... ¿de otra manera? –

+0

Ver la respuesta actualizada que usa attibute no basado en DB entonces. –

-1

Dependiendo de la bandera clima es verdadero o falso, utilice el método save(false) omitir la validación.

+3

'save (false)' omitirá toda la validación, no solo un método. – shime

+0

También es 'save (validate: false)', not 'save (false)' – Fritzz

+0

es 'save (false)' en Rails v2.3 – daslicious

0

Utilice el bloque en su validación algo así como:

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