Ruby on rails 在多次保存之前创建呼叫
在我的模型中有一个before_save回调函数,它在将两个字段保存到数据库之前对其进行加密Ruby on rails 在多次保存之前创建呼叫,ruby-on-rails,ruby-on-rails-4,rails-activerecord,Ruby On Rails,Ruby On Rails 4,Rails Activerecord,在我的模型中有一个before_save回调函数,它在将两个字段保存到数据库之前对其进行加密 class Account < ActiveRecord::Base before_save :encrypt_credentials, if: "!username.blank? && !password.blank?" def encrypt_credentials crypt = ActiveSupport::MessageEncryptor.new(ENV
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
为什么在保存之前要调用多次?我不喜欢上面链接的帖子的解决方案,我不想先新建/构建,然后保存。这是用户错误:(在调用account=account.create!之后,我有另一个代码在模型上调用save!。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
类帐户
选项1(可能是回调使用中的错误):
简短回答:保存后使用,而不是保存前使用
长答覆:
当您使用时:
account=account.new
account.save
你每次都在发射前保存钩子
选项2(可能是一个bug):
也许你真的触摸了唱片好几次
例如:
def create
@account = Customer.find(params[:customer_id]).accounts.create(account_params)
if @account.save
redirect_to customer_account_path(@account.customer.id, @account.id)
else
render :new
end
end
事实上,您正在使用create and save触碰它。在这种情况下,我建议:
def create
@account = Customer.find(params[:customer_id]).accounts.build(account_params)
if @account.save
redirect_to customer_account_path(@account.customer.id, @account.id)
else
render :new
end
end
Build不尝试保存记录,因此您不应该再有任何问题。希望这有帮助!祝您度过愉快的一天
def create
@account = Customer.find(params[:customer_id]).accounts.build(account_params)
if @account.save
redirect_to customer_account_path(@account.customer.id, @account.id)
else
render :new
end
end