3 methods (1 failed) that I came across are
1) use the observer in the active record in all the corresponding save, validation files
2) to open the active record and put the debugger instruction where ROLLBACK is started, and then run caller to determine the code that caused the error.
3) Failed: override active write methods and pause the exception. If I remember, this method does not raise any exceptions because the save methods are wrapped in a transaction.
Notes: Enable only if the mode is not Rails.env.production ?. Tested on Rails 3.2.13 using ruby 1.9.3.
1) Observer: 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)
When the server or console rails hits the breakpoint type in caller to get backtracking.
3) Override AR in design mode. TODO: only override if! Rails.env.production? Put this in 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
davidtingsu Aug 23 '13 at 19:28 2013-08-23 19:28
source share