Почему before_save не вызывается для моей модели ActiveRecord? - PullRequest
9 голосов
/ 10 июня 2011

Ничего не выводится на консоль, когда я использую IRB для создания нового экземпляра модели и сохранения, и я получаю сообщение об ошибке «ActiveRecord :: StatementInvalid: Mysql :: Error: столбец« user_id »не может быть нулевым», поэтому я предполагаю, before_save не вызывается. Я не могу понять, почему. Я даже пытался использовать фильтр before_save. Вот мой код:

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

1 Ответ

30 голосов
/ 10 июня 2011

Как вы можете видеть в документации , before_save происходит после проверки.В вашем случае проверка не удастся, и before_save никогда не будет вызван.

Поскольку цель вашего обратного вызова состоит в том, чтобы установить ваш объект в допустимое состояние до того, как произойдет проверка, попробуйте обратный вызов before_validation.

...