ActiveRecord:update_all在调试日志中显示查询,但不在DB中执行?

时间:2014-08-18 20:56:43

标签: ruby-on-rails postgresql activerecord ruby-on-rails-4

我在Rails模型中的before_destroy回调调用的函数中运行了以下更新查询:

Annotation.joins(:annotation_groups)
  .where({'annotation_groups.group_id' => self.id})
  .update_all({qc_approved: false}) if doc.in_qc?`

(我也尝试过以下更简单的版本来查看另一个角度是否有效:self.annotations.update_all({qc_approved: false})

两者都在“服务器开发日志”中生成以下SQL查询(在RubyMine中调试):

  

UPDATE "annotations" SET "qc_approved" = 'f' WHERE "annotations"."id" IN (SELECT "annotations"."id" FROM "annotations" INNER JOIN "annotation_groups" ON "annotation_groups"."annotation_id" = "annotations"."id" WHERE "annotation_groups"."group_id" = 159)

但是,据我所知,SQL永远不会导致数据库更新,即使之后的销毁过程正常。我可以在语句后直接设置断点并查看数据库,qc_approved字段仍然是真的。但是,我可以将语句复制并粘贴到Postgres控制台并运行它,并正确更新字段。

是否有人知道会导致此行为的原因? before_destroy是否存在于其自己奇怪的备用事务Universe中,导致像这样的奇怪行为?什么情况会导致SQL出现在服务器日志中但不会出现在数据库中?

1 个答案:

答案 0 :(得分:0)

由于上面的快速和有用的评论确认了较大事务中回调的性质,我想出来了......尽管有名称,before_destroy实际上是在依赖的destroy调用之后执行的,所以加入了{ {1}}表行在事务中调用依赖它的annotation_group语句之前被销毁。

更具体地说,我将UPDATE添加到:prepend => true定义中,以便在按预期销毁之前运行。