Q:

create calls before_save multiple times

I have a before_save callback in my model which encrypts 2 fields before they're saved to the database. 
class Account < ActiveRecord::Base
  before_save :encrypt_credentials, if: "! username.blank? && ! password.blank?" 

  def encrypt_credentials
    crypt = ActiveSupport::MessageEncryptor.new(ENV['KEY'])
    self.username = crypt.encrypt_and_sign(username)
    self.password = crypt.encrypt_and_sign(password)
  end

  def decrypted_username
    crypt = ActiveSupport::MessageEncryptor.new(ENV['KEY'])
    crypt.decrypt_and_verify(username)
  end

  def decrypted_password
    crypt = ActiveSupport::MessageEncryptor.new(ENV['KEY'])
    crypt.decrypt_and_verify(password)
  end
end

The situation is very similar to Devise models run before_save multiple times?.  When I call Model.create!(...) -  which includes the 2 fields that need to be encrypted, the before_save gets called twice, ending up in the fields being encrypted twice. 
Account.create!( 
{
  username: ENV['USERNAME'],
  password: ENV['PASSWORD']
})

Why is before_save called multiple times?  I don't like the solution of the post linked above and I don't want to do new/build followed by save. 

A:

It was user error :( After calling account = Account.create!,  I had other code which called save!  back on the model: account.foo = bar; account.save!.  This obviously called befor_save again and re-encrypted my fields.  I ended up with something like this:
class Account < ActiveRecord::Base
  before_save :encrypt_username, if: :username_changed? 
  before_save :encrypt_password, if: :password_changed? 

  def encrypt_username
    crypt = ActiveSupport::MessageEncryptor.new(ENV['KEY'])
    self.username = crypt.encrypt_and_sign(username)
  end

  def encrypt_password
    crypt = ActiveSupport::MessageEncryptor.new(ENV['KEY'])
    self.password = crypt.encrypt_and_sign(password)
  end

  def decrypted_username
    crypt = ActiveSupport::MessageEncryptor.new(ENV['KEY'])
    crypt.decrypt_and_verify(username)
  end

  def decrypted_password
    crypt = ActiveSupport::MessageEncryptor.new(ENV['KEY'])
    crypt.decrypt_and_verify(password)
  end
end

