我有这样的事情:
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的帮助。
答案 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