« Previous - Version 10/76 (diff) - Next » - Current version
Guillermo Gómez, 04/04/2012 01:43 pm


ActiveRecord validaciones

¿Cúando ocurren las validaciones?

Hay dos tipos de objetos Active Records, aquellos que corresponden a una fila dentro de la base de datos y aquellos que no. Cuando se crea un objeto fresco, por ejemplo usando el método new, dicho objeto no pertenece a la base de datos aún. Una vez que llame al método save, entonces será salvado apropiadamente en la base de datos en su respectiva tabla. Active Record usa el método de instancia new_record? para determinar si un objeto ya se encuentra en la base de datos o no.

El crear y salvar un nuevo registro ejecutará una operaciń SQL INSERT en la base de datos. Actualizar un registro existente ejecutará una operación SQL UPDATE.

Las validaciones son típicamente ejecutadas antes que dichos comandos sean enviados a la base de datos. Si cualquier validación falla, el objeto será marcado como inválido y Active Record no realizará la operación INSERT o UPDATE correspondiente. Esto evita almacenar objetos inválidos en la base de datos. Usted puede escoger el tener validaciones específicas a ser ejecutadas cuando el objeto es creado, salvado o actualizado.

Existen muchas formas de cambiar el estado de un objeto en la base de datos, algunos métodos disparan las validaciones, pero algunos no. Esto significa que es posible salvar un objeto en la base de datos en un estado inválido si usted no tiene cuidado.

Los siguientes métodos activan las validaciones y salvarán el objeto en la base de datos sólo si el objeto es válido:

  • create
  • create!
  • save
  • save!
  • update
  • update_attributes
  • update_attributes!

Un ejemplo simple.

1class Persona < ActiveRecord::Base
2end
>> p = Persona.new
    #<Persona id: nil, nombres: nil, apellidos: nil, cedula: nil, correo: nil, cargo: nil, created_at: nil, updated_at: nil>
>> p.new_record?
    true
>> p.save
    true
>> p.new_record?
    false

Evitando las validaciones

Los siguientes métodos evitan las validaciones y salvarán el objeto en la base de datos sin importar su validez. Deben ser utilizados con precaución.

  • decrement!
  • decrement_counter
  • increment!
  • increment_counter
  • toggle!
  • touch
  • update_all
  • update_attribute
  • update_column
  • update_counters

Note que save también tiene la habilidad de evitar las validaciones si se le pasa el argumento :validate => false. Esta técnica igualmente debe usarse con cuidado.

save(:validate => false)

valid? e invalid?

Para verificar si un objeto es válido o no, Rails usa el método valid?. También usted puede usarlo libremente. valid? activa las validaciones y devuelve true si no hay errores en el objeto, y false de cualquier otra forma.

1class Persona < ActiveRecord::Base
2  validates :nombres, :presence => true
3end
>> Persona.create(:nombres => "Juan Bimba").valid?
    true
>> Persona.create(:nombres => "").valid?
    false

Después de que Active Record ha ejecutado las validaciones, cualquier error encontrado estará disponible por medio del método de instancia errors que devuelve una conjunto de errores. Por definición un objeto es válido si dicho conjunto está vacío después de ejecutar las validaciones.

Note que un objeto instanciado con new no reportará errores incluso si técnicamente es inválido porque las validaciones no se ejecutando cuando se usa new.

>> p = Persona.new
    #<Persona id: nil, nombres: nil, apellidos: nil, cedula: nil, correo: nil, cargo: nil, created_at: nil, updated_at: nil>
>> p.errors
    #<ActiveModel::Errors:0xb3742594 @messages=#<OrderedHash {}>, @base=#<Persona id: nil, nombres: nil, apellidos: nil, cedula: nil, correo: nil, cargo: nil, created_at: nil, updated_at: nil>>

>> p.valid?
    false
>> p.errors
    #<ActiveModel::Errors:0xb3742594 @messages=#<OrderedHash {:nombres=>["can't be blank"]}>, @base=#<Persona id: nil, nombres: nil, apellidos: nil, cedula: nil, correo: nil, cargo: nil, created_at: nil, updated_at: nil>>

>> p.save
    false
>> p.save!
ActiveRecord::RecordInvalid: Validation failed: Nombres can't be blank

>> Persona.create!
ActiveRecord::RecordInvalid: Validation failed: Nombres can't be blank