2011-06-10 12 views
9

No se imprime nada en la consola cuando uso IRB para crear una nueva instancia de modelo y guardar, y obtengo un error "ActiveRecord :: StatementInvalid: Mysql :: Error: Column 'user_id' no puede ser nulo", así que supongo before_save no está siendo llamado. No puedo entender por qué. Incluso he intentado usar el filtro before_save. Aquí está mi código:¿Por qué before_save no se llama para mi modelo ActiveRecord?

require 'secure_resource/secure_resource_encryption' 

class Database < ActiveRecord::Base 
    belongs_to :username_encryption, :class_name => "Encryption", :foreign_key => :username_encryption_id 
    belongs_to :password_encryption, :class_name => "Encryption", :foreign_key => :password_encryption_id 

    # Virtual attribute to retrieve the decrypted username. 
    def username 
    if self.username_encryption.nil? 
     return nil 
    end 

    begin 
     return self.username_encryption.encryption 
    rescue SecureResourceError 
     raise SecureResourceError 
    end 
    end 

    # Provides a way to reset the username. 
    def username=(username) 
    if self.username_encryption.nil? 
     self.username_encryption = Encryption.new 
     self.username_encryption.encryption = username 
    end 
    end 

    # Virtual attribute to retrieve the decrypted password. 
    def password 
    if password_encryption.nil? 
     return nil 
    end 

    begin 
     return password_encryption.encryption 
    rescue SecureResourceError 
     raise SecureResourceError 
    end 
    end 

    # Provides a way to reset the password. 
    def password=(password) 
    if self.password_encryption.nil? 
     self.password_encryption = Encryption.new 
     self.password_encryption.encryption = password 
    end 
    end 

    def before_save 
    p 'ZZZZZZZZZZZZZZZ' 
    p self.user_id.to_s + ' ZZZZZZ' 
    p 'ZZZZZZZZZZZZZZZ' 
    self.username_encryption.user_id = self.user_id 
    self.username_encryption.save 
    self.username_encryption_id = self.username_encryption.id 

    self.password_encryption.user_id = self.user_id 
    self.password_encryption.save 
    self.password_encryption_id = self.password_encryption.id 
    end 
end 

Respuesta

25

Como se puede ver in the documtation, before_save sucede después validación. En su caso, la validación fallará y before_save nunca será invocado.

Dado que el objetivo de su devolución de llamada es establecer su objeto a un estado válido antes de la validación, intente con la devolución de llamada before_validation.

+0

Ahh, entonces el error de MySQL ocurre durante la validación. Por alguna razón, había supuesto que estaba sucediendo durante el guardado. Voy a intentar esto y ver qué pasa. ¿Cómo puedo decir explícitamente si pasa la validación? –

+0

La cosa es, en IRB, cuando creo una nueva instancia de Base de datos, establezco parámetros y llamo database.valid ?, true es devuelto. Entonces, ¿cómo podría ser esto un problema de validación? –

+0

@Chad Ah, no leí lo suficiente. Si MySQL está provocando el error, tus devoluciones de llamada 'before_validation' * y *' before_save' se han disparado y Rails está hablando con la base de datos. Uno de tus campos 'user_id' es nulo. Intenta usar 'logger.info' en lugar de' puts'/'p', que * no * escribe en la consola en Rails. – meagar

Cuestiones relacionadas