2017-02-26 52 views
0

我的模型中有一個before_save回調函數,它在將兩個字段保存到數據庫之前對其進行加密。before_save多次創建調用

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 

這種情況非常類似於Devise models run before_save multiple times?。當我調用Model.create!(...) - 其中包含需要加密的兩個字段時,before_save會被調用兩次,最終在兩次加密的字段中結束。

Account.create!(
{ 
    username: ENV['USERNAME'], 
    password: ENV['PASSWORD'] 
}) 

爲什麼before_save被多次調用?我不喜歡上面鏈接的帖子的解決方案,我不想做新的/構建,然後保存。

回答

0

這是用戶錯誤:(在調用account = Account.create!之後,我有其他代碼調用了保存模型:account.foo = bar; account.save !.這顯然調用了befor_save並重新加密我的領域。我結束了這樣的事情:

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