如何findActiveRecord ROLLBACK的原因
在日志中,我看到一个ROLLBACK
,但没有例外logging。 有没有办法找出是什么导致了ROLLBACK?
这里是日志的摘录:
Phone Load (0.4ms) SELECT "phones".* FROM "phones" WHERE "phones"."id" = $1 LIMIT 1 [["id", 980190963]] (0.2ms) BEGIN User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."phone_id" = 980190963 LIMIT 1 (0.2ms) ROLLBACK Phone Load (0.4ms) SELECT "phones".* FROM "phones" WHERE "phones"."id" = $1 LIMIT 1 [["id", 980190963]] User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."phone_id" = 980190963 LIMIT 1
用BANG保存logging'!' 所以它会造成运行时错误,你会知道它发生了什么
一种方法是手动将信息写入日志。 尝试从你的控制器这样的事情:
Rails.logger.info(@your_object.errors.inspect)
这应该输出所有失败的validation内容。
1)禁用before_create,before_sup,before_update并检查它保存的date
2)如果回滚是由这些方法之一引起的,请检查在不打算回滚的情况下这些方法返回true。
例如,如果你为布尔型字段设置默认值以避免零,你可能会这样做
def set_defaults_before_create self.my_boolean_field ||= false end
在这个例子中, set_defaults_before_create方法总是返回false ,从而回滚事务。 所以重构它返回true
def set_defaults_before_create self.my_boolean_field ||= false true end
3个方法(1个失败)我已经拿出来了
1)在所有相关的保存,validation方法上使用活动logging中的观察者
2)打开活动logging,并在触发ROLLBACKs的地方放一个debugging器语句,然后运行caller
来查找触发错误的代码。
3)失败:覆盖活动logging方法并暂停exception。 如果我记得这个方法没有捕获任何exception,因为保存方法被封装在一个事务中。
注意:只有在模式不是Rails.env.production时才能使用。 testingRails 3.2.13,使用ruby1.9.3。
1)观察者: http : //guides.rubyonrails.org/v3.2.13/active_record_validations_callbacks.html#observers
class ActiveRecordObserver < ActiveRecord::Observer observe "ActiveRecord::Base" def after_validation(model) debugger if model.errors.messages.any? Rails.logger.error "after validation" end def before_update(model) debugger if !model.valid? Rails.logger.error "before update" end def after_update(model) debugger if !model.valid? Rails.logger.error "after update" end def before_save(model) debugger if model.errors.messages.any? Rails.logger.error "#{model}" Rails.logger.error "before save" end def after_save(model) debugger if model.errors.messages.any? Rails.logger.error "after save" end end
2) https://github.com/rails/rails/blob/3-1-stable/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb#L231 cd`bundle show activerecord`
Put a debugger statement when where the rollback is executed. /Users/<user>/.rvm/gems/ruby-1.9.3-<env>/gems/activerecord-3.2.14/lib/active_record/connection_adapters/abstract/database_statements.rb 196 transaction_open = false 197 decrement_open_transactions 198 if open_transactions == 0 199 rollback_db_transaction 200 debugger => 201 rollback_transaction_records(true) 202 else 203 rollback_to_savepoint 204 debugger 205 rollback_transaction_records(false)
当Rails服务器或控制台在caller
击中断点types以获得回溯时。
3)在开发模式下重写AR。 TODO:只有覆盖!Rails.env.production? 把它放在app/config/initializers/active_record_or_any_file_name.rb
ActiveRecord::Base.class_eval do alias_method :old_save, :save alias_method :old_save!, :save! def save(*args) begin puts "#{self} save" Rails.logger.info "#{self} save" old_save(*args) rescue Exception => e debugger puts e end end def save!(*args) begin Rails.logger.info "#{self} save!" puts "#{self} save!" old_save!(*args) rescue Exception => e debugger puts e end end end
- Rails 3 / Form没有模型:我如何创build一个不绑定到模型的表单?
- ActiveRecord的Rails 3范围与类的方法
- 为什么所有的活动logging都讨厌?
- Ruby的Activerecord IN子句
- 如何计算ROR中特定字段中具有唯一值的logging数?
- 我怎么知道什么时候在Rails中“刷新”我的模型对象?
- 使用活动loggingsearch序列化的数据
- 如何处理Ruby on Rails错误:“请安装postgresql适配器:`gem install activerecord-postgresql-adapter'”
- 使用Rails 4,Model.scoped已被弃用,但Model.all不能替代它