Rails cache_digests触摸has_many关联

时间:2013-02-25 23:56:33

标签: ruby-on-rails caching

我有这样的事情:

class Suite < ActiveRecord::Base
  has_many :tests
end

class Test < ActiveRecord::Base
  belongs_to :suite
end

我正在使用cache_digests gem来进行片段缓存。 我希望在更新Suite对象时,子测试缓存过期。 我试图在touch: true关联中放置has_many但没有成功。

我该怎么做?

提前致谢


修改

我正在这样做我的缓存:

<% cache test do %>
  <tr>
   etc...
    <% cache test.suite do %>
      etc..
    <% end %>
  </tr>
<% end %>

但它不起作用,因为当我编辑套件时,他们的测试没有被触及。所以,我将缓存声明更改为:

<% cache [test, test.suite] do %>
   etc..
<% end %>

它的效果与预期一致。

当我编辑测试或套件时,其中一个被触及,因此,片段已过期,我按预期获得了新版本。

感谢@ taryn-east的帮助。

5 个答案:

答案 0 :(得分:4)

你是对的,touch: true并不适用于has_many关系。您可以使用after_save挂钩并手动更新所有关联的资源。例如......

class Post < ActiveRecord::Base
  has_many :assets
  after_save :touch_assets

  def touch_assets
    assets.update_all(updated_at: Time.now)
    # This does a single SQL call, but bypasses ActiveRecord in the process. See warning below.
    # SQL> UPDATE "assets" SET "updated_at" = '2014-03-25 22:37:55.208491' WHERE "assets"."post_id"  [["post_id", 2]]
  end
end

class Asset < ActiveRecord::Base
  belongs_to :post
end

警告:这会在更新资产时绕过ActiveRecord,因此如果资产需要依次触摸另一个对象,则无法正常工作。但是,您可以在touch_assets方法中添加一些额外的逻辑,以更新资产应该更新的对象。但这开始变得混乱。

答案 1 :(得分:3)

此页面:  https://github.com/rails/rails/issues/8759

建议使用after_save钩子:

class Post < ActiveRecord::Base
  has_many :assets
  after_save -> { self.touch }
end

class Asset < ActiveRecord::Base
  belongs_to :post
end

答案 2 :(得分:0)

更改片段缓存策略,使用类似:

<% cache [test, test.suite] do %>

我在评论中找到了这个答案。我只是想明确这是“答案。”

答案 3 :(得分:-2)

你需要添加

autosave: true 
如果您想强制父母更新孩子,请在has_many关联上

。触摸用于更新孩子 - &gt;父节点。

答案 4 :(得分:-5)

试试这个

    class Suite < ActiveRecord::Base
      has_many :tests
    end

    class Test < ActiveRecord::Base
      belongs_to :suite, :touch => true
    end