Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 如何查找ActiveRecord回滚的原因_Ruby On Rails_Activerecord - Fatal编程技术网

Ruby on rails 如何查找ActiveRecord回滚的原因

Ruby on rails 如何查找ActiveRecord回滚的原因,ruby-on-rails,activerecord,Ruby On Rails,Activerecord,在日志中,我看到一个回滚,但没有记录异常。有没有办法找出导致回滚的原因 以下是日志摘录: 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" = 9

在日志中,我看到一个
回滚
,但没有记录异常。有没有办法找出导致回滚的原因

以下是日志摘录:

  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

一种方法是手动将信息写入日志。从控制器中尝试以下操作:

Rails.logger.info(@your_object.errors.inspect) 
这应该会输出所有失败验证的内容。

我提出的3种方法(1种失败)是

1) 在所有相关的保存、验证方法上使用活动记录上的观察者

2) 打开活动记录并将调试器语句放在触发回滚的位置,然后运行
caller
以查明触发错误的代码

3) 失败:覆盖活动记录方法并在异常时暂停。如果我记得的话,这个方法不会捕获任何异常,因为save方法被包装在一个事务中

注意:仅当模式不是Rails.env.production?时启用?。在Rails 3.2.13上测试,使用ruby 1.9.3

1) 观察员:

1) 在创建前、保存前、更新前禁用,并检查其保存日期的位置

2) 如果回滚是由这些方法之一引起的,请检查当您不打算回滚时,这些方法是否返回true

例如,若您将布尔字段的默认值设置为避免nil,则可能会这样做

def set_defaults_before_create
  self.my_boolean_field ||= false
end
在此示例中,方法在创建之前设置\u默认值\u始终返回false,从而回滚事务。所以重构它以返回true

def set_defaults_before_create
  self.my_boolean_field ||= false
  true
end

用“砰”一声保存记录因此,它将产生一个运行时错误,您可以知道它发生在哪里

回滚前后的日志中有什么内容?没有错误。而且,很奇怪的是,它一次使用事务,下一次不使用。除非这两个部分是不相关的。知道是什么原因导致在事务中选择吗?可能是您正在进行一些保存/更新。你能粘贴与日志对应的代码吗?解决了我的问题:rails不喜欢在回调过程中修改具有直通关联的关联模型,不管它是在模型中还是在观察者中。没有例外消息或任何东西;只是回滚。我花了大约一天的时间调试这个问题。非常感谢:)第二点解决我的问题。方法需要返回true,我认为它用于验证目的,即使我们将其用于其他目的。我在模型中定义了一个函数
destroy
,从磁盘中删除与记录相关的其他文件时遇到了类似的问题,然后如果文件丢失,函数返回的不是true,因此,我在最后一行添加了
true
,一切正常。谢谢我不知道。在我的例子中,我得到了一个
destroy
的回滚,在这种情况下,选择的答案似乎对我有帮助,但这个答案不适用。我希望我能多次投票。它救了我好几次。谢谢你,伙计,我很快就发现了问题!(我遇到了一个类似的问题,回滚不是由任何异常引起的,因此没有任何救援块会给出原因。按照@davidtimgsu的建议放置调试点有助于对其进行本地化。在ActiveRecord 5.2.3中,在
active\u record/connection\u adapters/abstract/transaction.rb
下有一行内容为
Thread.current.status==“正在中止”
。这是我的回滚的原因,因为外部进程正在终止当前线程,并且当前线程中的SURE语句中的所有事务都在回滚。
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
def set_defaults_before_create
  self.my_boolean_field ||= false
end
def set_defaults_before_create
  self.my_boolean_field ||= false
  true
end