更新: 是否会调用update_attributes获取自己的事务?
我查看了this问题,除了这个问题之外,我还决定将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
答案 0 :(得分:3)
所以它发生了3次,因为个人资料被保存了3次:一次是在用户保存时(我假设User accepts_nested_attributes_for :profile
,一次是在你拨打update_attributes(:first_time => true,...)
时,一次是在你打电话给保存时if params[:resume]
阻止。每次保存都会创建一个新的交易(除非其中一个已在进行中),您最终会多次调用after_commit
after_commit
确实采用:on
选项(可以采用值:create
,:update
,:destroy
),以便您可以将其限制为新记录。这显然会在第一次保存时触发,因此您将无法看到配置文件的简历等等。
您还可以在一个事务中包含所有这些更新,在这种情况下after_commit
只会被调用一次,无论通过执行类似
User.transaction do
if @user.save
...
end
end
如果引发异常,事务将被回滚(如果你想要纾困,你可以提出ActiveRecord::Rollback
)