我如何通过关系来强制rails对has_many不使用缓存的结果?

问题描述 投票:11回答:5

我有以下三种模型(经过简化):

class A < ActiveRecord::Base
  has_many :bs
  has_many :cs, :through => :bs
end

class B < ActiveRecord::Base
  belongs_to :a
  has_many :cs
end

class C < ActiveRecord::Base
  belongs_to :b
end

[A.cs似乎在我第一次不想使用时(每个对象)被缓存了。

这是一个突出显示问题的控制台会话(绒毛已被编辑)

首先,它的工作方式

rails console
001 > b = B.create
002 > c = C.new
003 > c.b = b
004 > c.save
005 > a = A.create
006 > a.bs << b
007 > a.cs
=> [#<C id: 1, b_id: 1>]

这的确是您所期望的。 a.cs通过a.bs关系进展顺利。

现在用于缓存说明

008 > a2 = A.create
009 > a2.cs
=> []
010 > a2.bs << b
011 > a2.cs
=> []

因此,对a2.cs的第一次调用(导致数据库查询)完全正确地没有返回Cs。但是,第二个调用显示出C的明显不足,即使Cs应该存在(没有发生数据库查询)也是如此。

[只是为了考验我的理智不应该受到指责

012 > A.find(a2.id).cs
=> [#<C id: 1, b_id: 1>]

同样,执行数据库查询以获取A记录和关联的C。

因此,回到问题所在:如何强制Rails不使用缓存的结果?我当然可以辞职去做这种解决方法(如控制台步骤12所示),但是由于在只需要一个查询的情况下会导致另外两个查询,所以我宁愿不要。

ruby-on-rails caching has-many-through
5个回答
16
投票

我对此问题进行了更多研究。尽管使用clear_association_cache非常方便,但是在使缓存无效的每个操作之后添加它都不会感到DRY。我认为Rails应该能够对此进行跟踪。幸运的是,有一种方法!


2
投票

((编辑:请参见Daniel Waltrip的答案,他远胜于我的)


2
投票

我发现了另一种禁用查询缓存的方法。在您的模型中,只需添加一个default_scope


2
投票

所有关联方法都是围绕缓存构建的,它使最新查询的结果可用于进一步的操作。缓存甚至在方法之间共享。例如:


0
投票

要清除缓存,请使用.reload

© www.soinside.com 2019 - 2024. All rights reserved.