2012-05-23 12 views
17

Tengo una pregunta muy nueva. ¿Cómo puedo verificar que el objeto del modelo sea válido con nuevos parámetros ANTES de actualizarlo?Rieles 3: compruebe que el objeto sea válido con params antes de la actualización

Quiero transformar esa:

def update 
    @obj = SomeModel.find(params[:id]) 

    if @obj.update_attributes(params[:obj]) 
    # That have been updated 
    else 
    # Ups, errors! 
    end 
end 

Para algo así:

def update 
    @obj = SomeModel.find(params[:id]) 

    if @obj.valid_with_new_params(params[:obj]) 
    @obj.update_attributes(params[:obj]) 
    else 
    # Ups, errors! 
    end 
end 

Respuesta

35

Para actualizar los atributos sin necesidad de guardarlos, puede utilizar

@obj.assign_attributes(params[:obj]) 

a continuación, para comprobar si el objeto es válido, puede llamar

@obj.valid? 

Si el objeto es no válida , Se puede ver los errores (sólo después de llamar .valid?) llamando

@obj.errors 

Si el objeto es válida, puede guardarlo llamando

@obj.save 

Sin embargo, todo esto generalmente no es necesario Si el objeto no es válido, ActiveRecord no guardará el objeto en la base de datos, por lo que todos los cambios de atributo se olvidan cuando abandona la acción del controlador.

Además, dado que un registro no válido no se guardará en la base de datos, siempre puede llamar a Object.find() nuevamente para recuperar el objeto original.

+4

Después de @ obj.attributes (params [: obj]), llame a @ obj.save. –

+0

El método 'attributes()' como se muestra en esta respuesta en el momento de escribir esto está en desuso. En su lugar, use 'assign_attributes (new_attributes)' o el alias 'attributes = (new_attributes)'. Por lo tanto, la primera línea en esta respuesta debe ser '@ obj.assign_attributes (params [: obj])'. Ver [ActiveRecord :: AttributeAssignment] (http://api.rubyonrails.org/classes/ActiveRecord/AttributeAssignment.html) – user664833

+0

Re: 'assign_attributes (new_attributes)' - tenga en cuenta que * los únicos atributos establecidos son los nombrados por las teclas en el params hash *. Entonces, si tiene un objeto existente, puede agregar/fusionar solo un subconjunto de atributos. – user664833

0

no se guardará el objeto si el argumento pasado no produce un objeto válido, por lo que puede usa tu camino muy bien. Puede ver los errores (si los hay) utilizando la matriz @obj.errors.

0

update_attributes método validate object y devuelve false si el objeto no es válido. Por lo tanto, sólo puede escribir:

if @obj.update_attributes(params[:obj]) 
    # That have been update 
else 
    # Ups, errors! 
end 
3

Usted puede llamar al método valid? para ejecutar las validaciones.

Esto no garantiza que un posterior guardado tenga éxito si algunas de sus validaciones dependen del estado de otros objetos en la base de datos. Te ahorro también podría fallar por razones ajenas a las validaciones (por ejemplo, una restricción de clave externa)

No estoy seguro de por qué te gustaría este patrón

+1

estoy ahorrando unos pocos objetos de diferentes modelos. Recolecto errores de validaciones de cada modelo y luego los muestro en una ventana emergente. – ExiRe

0

La respuesta es que se puede definir un método

def valid_with_new_params(hash) 
    self.attributes = hash 
    valid? 
end 

Pero eso sería innecesario porque @obj.update_attributes(params[:obj]) vuelve true si el obj se ha actualizado correctamente y false lo contrario. Tenga en cuenta también que internamente el método update_attributes ejecuta todas las validaciones en el @obj para que tenga @obj.errors disponible si la actualización falla.

+1

'atributos =' método está en desuso en las nuevas versiones de Rails – apneadiving

+0

Gracias @apneadiving no sabía de eso :) – Gerry

0

Para actualizar los atributos sin tener que guardarlos

@obj.attributes = params[:obj] 0r 
@obj.attributes = {:name => “Rob”} 

A continuación, comprobar si el objeto es válido

@obj.valid? 

Para comprobar si hay cualquier error

@obj.errors 
Cuestiones relacionadas