【问题标题】:Can't reload ActiveRecord association from controller无法从控制器重新加载 ActiveRecord 关联
【发布时间】:2010-11-01 05:57:49
【问题描述】:

为此花了一个工作日。

我有

class Box
  has_many :users, :through => :subscriptions
end

我还有自定义的 insert_new_usersassociate_with(new_users) 方法,它们使用多个 INSERT 快速完成工作。无论如何,他们工作得很好。我在“associate_with”方法的末尾也有这一行:

def associate_with
  # mysql INSERT here
  self.users(true) # Should force reload
end

它在测试环境(控制器和模型测试)中运行时按预期工作,如果我删除 true 参数,它会按预期失败,这会强制重新加载。如果我 update_attributes 模型,它也可以从 script/console 在开发中工作。但是当我尝试从控制器update_attributes 时,开发或生产失败。它根本不会重新加载关联,我可以在日志中看到它,其中显示此查询的“CACHE (0.0ms)”。

奇怪的是 - 它以前工作过,但由于某些原因,我无法确定它停止工作的那一刻。我希望也许有人知道这怎么可能。

【问题讨论】:

    标签: ruby-on-rails associations reload


    【解决方案1】:

    我能够完全清除缓存的唯一方法是调用reload。例如,您可以调用

    User.reload

    它应该强制清除缓存,包括任何关系或关联。

    【讨论】:

      【解决方案2】:

      您将看到 ActiveRecord SQL 查询缓存的效果。

      在对 uncached 的调用中包装对 users 关联的 pre-INSERT 引用

      self.class.uncached do
        # ...
      end
      

      这将阻止 ActiveRecord 缓存块内的任何查询结果。如果您在很多地方都有代码,这可能会很烦人。

      您还可以在完成插入后通过调用connection.clear_query_cache 清除缓存。

      【讨论】:

      • 不幸的是,从模型内部调用时,它显示未定义的方法“未缓存”。
      • 好收获。它是一个类方法,而不是一个实例。我在答案中确定了范围。
      • 那么这是 Rails 中的错误吗?在我看来,调用 reload 真的应该重新加载。尽管 SQL 查询缓存可能足够聪明,可以知道数据库实际上并没有改变。在这种情况下,这并不是真正值得担心的事情。
      【解决方案3】:

      到目前为止,我已经能够通过以下方式欺骗 AR:

      def associate_with
        # mysql INSERT here
        @users = self.users.find(:all, :conditions => ['users.id IS NOT NULL'])
      end
      
      def users
        @users || self.users
      end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-07
        • 2014-11-20
        • 2012-10-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多