2011-04-14 26 views
3

我們的應用程序在控制器中使用Rails.cache來緩存視圖範圍之外的某些項目(如元標記),然後在視圖的大部分上使用fragment_caching。Rails是否有用於過期緩存的標籤?

視圖緩存一個主模型,但我們已經從5其他模型(不是由協會連接),該主緩存中使用的數據。在主模型上用清掃器清理碎片很容易,但這些附加模型也會更改,並且需要觸發此頁面過期。

我們不能使用正則表達式路由來刪除緩存鍵,因爲我們必須僅通過主模型來引用此緩存項 - 其他模型由我們在緩存塊中執行的昂貴查詢來確定控制器。

確實Rails 3中有一種方法基本上使用標籤標誌着一個緩存條目,所以我們可以垃圾只要任何頁面變化的6款車型,但我們仍然可以找到只有主緩存條目模型的關鍵?


下面是一些僞代碼表達的想法:

在控制器

@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 

在視圖

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

我的果阿L:

  • 我: 「哦,頁面@cache_key發生了變化,讓我們終止它!」
  • 的Rails:Okay, easy!
  • 我: 「一個類似的網頁,改變了他們的第一張照片,我該怎麼辦?」
  • 的Rails:Umm... #(*$^*@ .. does ... not ... compute.
+0

一些緩存系統比別人有更多的功能。你打算使用哪個? – tadman 2011-04-14 15:07:26

+0

我還沒有找到一個支持類標籤系統。內置緩存,cache_fu和cache_money都不支持標籤類系統。 – Kelly 2011-04-14 15:09:48

+0

你看過創建一個Observer來爲你管理嗎? – tadman 2011-04-14 16:00:50

回答

2

就像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語句),我這樣做高速緩存塊中:

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)} 

在我的我的觀察員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 
0

有怎樣的Rails的一個很好的解釋生成內容過期的標籤在這個視頻http://railslab.newrelic.com/2009/02/19/episode-8-memcached

短,如果它是,如果你通過你的整個對象到緩存它會生成一個使用時間戳的緩存鍵,當你改變你的對象時它將被更新。

+0

請注意,上面的視頻是用於memcached的,但cahche密鑰生成不是特定於此的 – 2011-04-17 21:39:27

0

收銀員可能會有所幫助。 「基於標記的緩存」

# in your view 
cache @some_record, :tag => 'some-component' 

# later 
Cashier.expire 'some-component' 

https://github.com/twinturbo/cashier