gpt4 book ai didi

ruby-on-rails - Rails 是否有使缓存过期的标签?

转载 作者:行者123 更新时间:2023-12-01 04:11:45 25 4
gpt4 key购买 nike

我们的应用程序在 Controller 中使用 Rails.cache 来缓存 View 范围之外的一些项目(如元标记),然后在 View 的主体上使用 fragment_caching。

View 缓存一个主模型,但我们在该主缓存中使用了来自5 个其他模型(未通过关联连接)的数据。在主模型上使用清扫器很容易使片段过期,但那些附加模型也会发生变化,需要触发此页面过期。

我们不能使用正则表达式路由来删除缓存键,因为我们必须仅通过主模型引用该缓存条目——其他模型由我们在 Controller 的缓存 block 内执行的昂贵查询确定.

Rails 3 有没有办法本质上使用标签 来标记缓存条目,这样当页面上的 6 个模型中的任何一个发生变化时我们都可以将其丢弃,但我们仍然可以找到缓存条目仅来自主模型的 key ?


这里有一些虚拟代码来表达这个想法:

在 Controller 中

@cache_key = "/page/#{params[:name]}/#{params[:id]}"
unless fragment_exist? ( { :slug => @cache_key })
# run our processes here that will be needed in the view,
# then cache the data that is used outside the view
Rails.cache.write(@cache_key, { (data goes here) } )
# run our expensive query here:
@similar_pages = Page.pricey_query!.limit(5).all
else
cached = Rails.cache.read(@cache_key)
end

在 View 中

- cache( {:slug => @cache_key} ) do
- @similar_pages.each do |page|
= image_tag page.photos.first.image.url
-# more pretty stuff here

我的目标:

  • 我:“哦,页面@cache_key 已经改变了,让它过期吧!”
  • Rails: 好的,简单!
  • :“其中一个相似的页面更改了他们的第一张照片,我该怎么办?”
  • Rails: 嗯... #(*$^*@ .. 不...不...计算。

最佳答案

正如 tadman 在问题的评论中所述,我必须发明自己的解决方案,因为 Rails 在技术上不允许在我需要它们的意义上使用标签。对于那些有兴趣做类似事情的人来说,这是一个通用的解决方案:

我创建了一个名为 SimilarPages 的新表:

create_table :similar_pages, {:id => false} do |t|
t.integer :page_id, :similar_page_id
# you could also do `t.string :tag_name` or similar
end
add_index :similar_pages, :page_id
add_index :similar_pages, :similar_page_id

从技术上讲,我可以在 Pages 上建立自引用 has_many 关系,但我决定不这样做,因为我永远不需要那样引用它。我刚刚创建了一个简单的 SimilarPage 模型:

class SimilarPage < ActiveRecord::Base
belongs_to :page
belongs_to :similar_page, :class_name => 'Page'
end

然后使用 ar-extensions(因为我很懒,也因为我想在一个 INSERT 语句中执行此操作),我在缓存 block 中执行此操作:

SimilarPage.delete_all("page_id = '#{@page_id}'")
SimilarPage.import [:page_id, :similar_page_id], @similar_pages.collect {|s| SimilarPage.new(:page_id=>@page_id,:similar_page_id=>s.id)}

在我的 Observer 的 expire_cache_for 方法中,我这样做:

SimilarPage.where(:similar_page_id => expiring_page.id).all.each do |s|
ActionController::Base.new.expire_fragment(/page_show__#{s.page_id}__.*/)
# the regexp is for different currencies being cached ^
Rails.cache.delete("page_show_#{s.page_id}")
end

关于ruby-on-rails - Rails 是否有使缓存过期的标签?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5665152/

25 4 0