在日志中我看到ROLLBACK
,但没有记录异常。有没有办法找出导致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
答案 0 :(得分:87)
用BANG'保存记录'!'因此它会产生运行时错误,你会知道它发生在哪里
答案 1 :(得分:47)
一种方法是手动将信息写入日志。从您的控制器尝试这样的事情:
Rails.logger.info(@your_object.errors.inspect)
那应该输出失败的所有验证的内容。
答案 2 :(得分:21)
1)禁用 before_create,before_save,before_update 并检查它保存当天的位置
2)如果回滚是由其中一种方法引起的,请在不打算回滚时检查这些方法是否返回true。
例如,如果你为boolean字段设置默认值以避免nil,你可能会这样做
def set_defaults_before_create
self.my_boolean_field ||= false
end
在此示例方法中, set_defaults_before_create 始终返回 false ,从而回滚您的交易。所以重构它以返回真实的
def set_defaults_before_create
self.my_boolean_field ||= false
true
end
答案 3 :(得分:7)
我提出的3种方法(1次失败)是
1)在所有相关的保存,验证方法上使用活动记录上的观察者
2)打开活动记录并将调试器语句放在触发ROLLBACK的位置,然后运行caller
以查明触发错误的代码。
3)失败:覆盖活动记录方法并暂停异常。如果我记得这个方法没有捕获任何异常,因为save方法被包装在一个事务中。
注意:仅在模式不是Rails.env.production时启用?使用ruby 1.9.3在Rails 3.2.13上测试。
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`s束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
中的断点类型以获取回溯时。
3)在开发模式下覆盖AR。 TODO:只覆盖if!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