2

我正在顯示餐廳菜單的頁面上工作。我有2個模型:FoodMenu has_many:產品和產品belongs_to:food_menu。我沒有這兩種型號的控制器。取而代之的是,我使用的是「pages_controller.rb」顯示每個FoodMenu及其產品具有「菜單」行動:Rails 3緩存:如何使用帶有Action和Fragment緩存的清掃器來使緩存過期?

def menus 
@food_menus = FoodMenu.includes(:products).all 
end 

我想用行動緩存菜單頁面(本地主機:3000 /菜單)它正在工作,但當我更新,創建或銷燬產品時,我無法讓緩存過期。

在的「pages_controller.rb」前,我有:

caches_action :menus 
cache_sweeper :pages_sweeper 

我想在這裏使用的示例代碼在app /清掃創造產品單獨清潔工和FoodMenu型號:http://guides.rubyonrails.org/caching_with_rails.html#sweepers,但沒沒有工作。然後,我讀了一個SO條目,清掃人員應該觀察控制器使用的所有模型,所以我認爲這意味着我必須創建一個「pages_sweeper.rb」,它觀察Product和FoodMenu模型,並過期「菜單」操作。那也行不通。我究竟做錯了什麼?這裏是我現在在「pages_sweeper.rb」中:

class PagesSweeper < ActionController::Caching::Sweeper 
observe Product, FoodMenu 

# If our sweeper detects that a Product was created call this 
def after_create(product) 
    expire_cache_for(product) 
end 

# If our sweeper detects that a Product was updated call this 
def after_update(product) 
    expire_cache_for(product) 
end 

# If our sweeper detects that a Product was deleted call this 
def after_destroy(product) 
    expire_cache_for(product) 
end 

def after_create(food_menu) 
    expire_cache_for(food_menu) 
end 

# If our sweeper detects that a FoodMenu was updated call this 
def after_update(food_menu) 
    expire_cache_for(food_menu) 
end 

# If our sweeper detects that a FoodMenu was deleted call this 
def after_destroy(food_menu) 
    expire_cache_for(food_menu) 
end 


private 
def expire_cache_for(product) 
# Expire the menus action now that we added a new product 
expire_action(:controller => 'pages', :action => 'menus') 

# Expire a fragment 
expire_fragment('all_available_products') 
end 

def expire_cache_for(food_menu) 
# Expire the menus page now that we added a new FoodMenu 
expire_action(:controller => 'pages', :action => 'menus') 

# Expire a fragment 
expire_fragment('all_available_food_menus') 
end 
end  

回答

0

我終於明白了!我能夠使片段和動作緩存起作用。從服務器日誌看來,動作緩存似乎要快得多,所以這就是我正在部署的內容。

對於片段緩存,我創建了觀察二者FoodMenu與產品和到期,我在部分創建的,像這樣的片段的「food_menu_sweeper.rb」:

class FoodMenuSweeper < ActionController::Caching::Sweeper 
observe FoodMenu, Product 

def after_save(food_menu) 
    expire_cache(food_menu) 
end 

def after_destroy(food_menu) 
    expire_cache(food_menu) 
end 

def after_save(product) 
    expire_cache(product) 
end 

def after_destroy(product) 
    expire_cache(product) 
end 

private 

def expire_cache(food_menu) 
    expire_fragment("menu items") 
end 

def expire_cache(product) 
    expire_fragment("menu items") 
end 

end 

下面是在該部分的片段:

<% cache("menu items") do %> 
    <% for food_menu in FoodMenu.full_list %> 
    ... 
<% end %> 
<% end %> 

FoodMenu.full_list被稱爲片段內緩存數據庫查詢,以及,其在food_menu.rb模型中定義:

def self.full_list 
    FoodMenu.includes(:products).all 
end 

然後,這裏的關鍵是將cache_sweeper放在「application_controller.rb」中!這暗示至關重要來自閱讀本SO條目:Rails - fragment cache not expiring

cache_sweeper :food_menu_sweeper 

這一切工作就像一個魅力。當我刷新頁面時,從緩存中讀取片段並且不進行數據庫調用。一旦我更新了一個產品或一個food_menu,緩存被清除,新的數據出現,然後被緩存。

對於動作緩存,我說:

caches_action :menus 

在我的 「pages_controller.rb」,然後取出從部分片段緩存,並在food_menu_sweeper更換

expire_fragment("menu items") 

。RB,具有:

expire_action(:controller => '/pages', :action => 'menus') 

這裏的關鍵是之前的「頁面」的斜線,這是我通過這個SO條目中找到:rails caching: expire_action in another namespace

沒有斜線,我得到一個「不能轉換符號轉換爲整數「時通過ActiveAdmin接口更新項目時出錯。

Yay for determination,Google,and Stack Overflow!

+0

這是否意味着片段緩存和動作緩存不能用於相同的緩存策略,即它是一個或另一個?我遇到了一個片段緩存過期問題,該片段緩存駐留在我正在使用caches_action的視圖的一部分中。 – Pete 2012-02-16 09:47:30