2010-09-22 3 views
4

Я пытаюсь реализовать Cache Sweeper, который будет фильтровать определенное действие контроллера.Rails Cache Sweeper

class ProductsController < ActionController 
    caches_action :index 
    cache_sweeper :product_sweeper 

    def index 
     @products = Product.all 
    end 

    def update_some_state 
     #... do some stuff which doesn't trigger a product save, but invalidates cache 
    end 
end 

Sweeper Класс:

class ProductSweeper < ActionController::Caching::Sweeper 
    observe Product 

    #expire fragment after model update 
    def after_save 
     expire_fragment('all_available_products') 
    end 

    #expire different cache after controller method modifying state is called. 
    def after_update_some_state 
     expire_action(:controller => 'products', :action => 'index') 
    end 
end 

ActiveRecord обратный вызов 'after_save' будет работать нормально, но обратный вызов на действия контроллера 'after_update_some_state' никогда, кажется, называется.

ответ

4

Похоже, мне просто не хватало имя контроллера при попытке получить обратные вызовы для действий контроллера. Мой Sweeper должен быть:

class ProductSweeper < ActionController::Caching::Sweeper 
    observe Product 

    #expire fragment after model update 
    def after_save 
     expire_fragment('all_available_products') 
    end 

    #expire different cache after controller method modifying state is called. 
    def after_products_update_some_state 
     expire_action(:controller => 'products', :action => 'index') 
    end 

    #can also use before: 
    def before_products_update_some_state 
     #do something before. 
    end 
end 
+0

Итак, метод 'after_save' может использоваться вместо вызова' after_create' и 'after_update'? –

3

Я думаю, что ваш уборочную должен выглядеть следующим образом:

class ProductSweeper < ActionController::Caching::Sweeper 
    observe Product 

    def after_save(product) 
    expire_cache(product) 
    end 

    def after_destroy(product) 
    expire_cache(product) 
    end 

    private 

    def expire_cache(product) 
    expire_fragment('all_available_products') 
    expire_page(:controller => 'products', :action => 'index') 
    end 

after_index не обратный вызов, если не определить.

В контроллере следует указать те действия, в которых уборщик должен быть вызван, в успокоительной, как эти действия должны быть create, update, destroy, поэтому ваше объявление контроллер должен выглядеть следующим образом:

class ProductsController < ActionController 
    caches_action :index 
    cache_sweeper :product_sweeper, :only => [:create, :update, :destroy] 

    def index 
    @products = Product.all 
    end 

    def create 
    @product = Product.new(params[:product]) 

    if @product.save # triggers the sweeper. 
     # do something 
    else 
     # do something else 
    end 
    end 

    # update and stuff ... 
end 

Я надеюсь, что это помогает !

+0

кэша-Sweeper документов говорят:. «Подметальные являются ограничителями мира кэширования и отвечает за истекающие кэша, когда объекты модели изменения Они делают это, будучи половинами наблюдателей, половина-фильтры и реализации обратные вызовы для обеих ролей ». Не означает ли это, что он добавит after_index в качестве обратного вызова фильтра? http://api.rubyonrails.org/classes/ActionController/Caching/Sweeping.html –

+0

Нет, подметальные машины не определяют обратные вызовы фильтра, они работают почти как наблюдатели, большая разница (с моей точки зрения) заключается в том, что вы необходимо указать, для каких действий будет работать наблюдатель, а также вы получите доступ к некоторым объектам и методам контроллера, например: 'expire_cache',' session', 'params' и т. д. ... – jpemberthy

+0

После рассмотрения моего оригинала post, я понял, что попытка показать то, что я хотел выполнить, используя индекс, как пример моего действия, который я пытался обернуть, может быть софизированием. Я обновил свой оригинальный пример, чтобы быть немного более ясным. –

Смежные вопросы