gpt4 book ai didi

ruby-on-rails - after_commit 回调被多次调用

转载 作者:行者123 更新时间:2023-12-04 06:01:41 27 4
gpt4 key购买 nike

更新:
对 update_attributes 的调用是否会获得它自己的事务?

我看过 this问题以及除该问题之外的其他原因,我决定将 after_commit 作为正确的钩子(Hook)。问题是它被多次(恰好三次)调用。代码解释起来有点复杂,但基本上有一个配置文件模型

include Traits::Blobs::Holder

在 holder.rb 我有:
  module ClassMethods

def belongs_to_blob(name, options = {})
clazz = options[:class_name] ? options[:class_name].constantize : Blob
foreign_key = options[:foreign_key] || :"#{name}_id"

define_method "save_#{name}" do
blob = self.send(name)
if self.errors.any? && blob && blob.valid?
after_transaction do
blob.save!
#self[foreign_key] = blob.id
#save resume anyway
self.update_attribute(foreign_key, blob.id)
end
end
end
after_validation "save_#{name}"

belongs_to name, options

accepts_nested_attributes_for name
end

end

最后在 profile.rb 本身我有:
after_commit :send_messages_after_registration!

protected

def send_messages_after_registration!
Rails.logger.debug("ENTERED : send_messages_after_registration " + self.owner.email.to_s)
if self.completed?
Rails.logger.debug("completed? is true " + self.owner.email.to_s)
JobSeekerNotifier.webinar_notification(self.owner.id).deliver
Resque.enqueue_in(48.hours, TrackReminderWorker, self.owner.id)
end
end

似乎该方法输入了3次。几天来我一直在尝试解决这个问题,因此您可以提供任何指导,我们将不胜感激。

Controller 代码:
def create
@user = Customer.new(params[:customer].merge(
:source => cookies[:source]
))
@user.require_password = true

respond_to do |f|
if @user.save
promote_provisional_user(@user) if cookies[:provisional_user_id]

@user.profile.update_attributes(:firsttime => true, :last_job_title => params[:job_title]) unless params[:job_title].blank?

if params[:resume]
@user.profile.firsttime = true
@user.profile.build_resume(:file => params[:resume])
@user.profile.resume.save
@user.profile.save
end
...
end

最佳答案

所以它发生了 3 次,因为配置文件被保存了 3 次:一次是保存用户时(我假设 User accepts_nested_attributes_for :profile ,一次是当你调用 update_attributes(:first_time => true,...) 时,一次是当你在 if params[:resume] block 中调用 save 时。每次保存创建一个新事务(除非一个已经在进行中)你最终会多次调用 after_commitafter_commit确实需要 :on选项(可以取值 :create:update:destroy ),以便您可以将其限制为新记录。这显然会在第一次保存时触发,因此您将无法看到个人资料的简历等等。

您还可以将所有这些更新包装在单个事务中,在这种情况下 after_commit只被调用一次,无论通过执行类似的操作在事务中进行了多少次保存

User.transaction do
if @user.save
...
end
end

如果引发异常,事务将回滚(如果您想退出,可以提出 ActiveRecord::Rollback)

关于ruby-on-rails - after_commit 回调被多次调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8750459/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com