Ruby on rails 在多次调用提交回调之后

Ruby on rails 在多次调用提交回调之后,ruby-on-rails,ruby-on-rails-3,callback,Ruby On Rails,Ruby On Rails 3,Callback,更新: 是否一个更新_属性的调用得到了它自己的事务 我已经考虑了这个问题,除了这个问题之外,我还决定选择after_commit作为合适的钩子。问题是它被多次(准确地说是三次)调用。代码解释起来有点复杂,但基本上有一个配置文件模型 include Traits::Blobs::Holder 在holder.rb中,我有: module ClassMethods def belongs_to_blob(name, options = {}) clazz = option

更新: 是否一个更新_属性的调用得到了它自己的事务

我已经考虑了这个问题,除了这个问题之外,我还决定选择after_commit作为合适的钩子。问题是它被多次(准确地说是三次)调用。代码解释起来有点复杂,但基本上有一个配置文件模型

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次。几天来我一直在努力解决这个问题,希望您能提供指导

控制器代码:

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次:一次是在用户被保存时(我假设
用户接受了:profile
的\u嵌套的\u属性),一次是在调用
update\u attributes(:first\u time=>true,…)
时,一次是在
if params[:resume]中调用save时
block。每次保存都会创建一个新事务(除非已有一个事务正在进行中),您在提交后会多次调用

提交后
确实会使用
:on
选项(可以使用值
:create
:update
:destroy
),这样您就可以将其限制为新记录。这显然会在第一次保存时触发,这样您就无法看到配置文件的结果等等

此外,您还可以将这些更新全部打包到一个事务中,在这种情况下,在只调用一次_commit之后,
,无论事务中通过执行以下操作进行了多少次保存

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

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

配置文件调用是否属于\u-to\u-blob?调用代码是什么样子的?使用控制器代码更新了我的问题是的。配置文件具有以下关联:
属于\u-blob:resume
这里有一个好问题:与事务回调相关的关联方法(如:属于\u-to\u-blob)何时被调用?您能否解释一下我是如何调用的
将这些更新全部打包到一个事务中
听起来像是想要的行为。感谢您的帮助!这是一个好主意,但它似乎仍然发送两封电子邮件。然后您可能正在别处调用save。记录调用堆栈(调用方)或在回调中设置断点,以查看调用方从何处调用您