views:

129

answers:

2

Hi there, I've got a sweeper that's supposed to expire a few action caches. Even though the debugger stops immediately before the call to expire_action, it's not actually expiring the action. Any idea what could be going on?

Here are the relevant sweeper and controller.

#company_sweeper.rb (in 'models' directory)

class CompanySweeper < ActionController::Caching::Sweeper
  observe Company

  def after_save(company)
    expire_cache(company) if company.final_save && company.valid?
  end

  def expire_cache(company)

    debugger                                              <= #debugger stops here!
                                                             right before the call
                                                             I'm trying to make.

    expire_action :controller => 'reports', 
                  :action => 'full_report'
  end
end

#reports_controller.rb

class ReportsController < ApplicationController
  layout false
  caches_action :full_report, :supplier_list, :service_categories
  cache_sweeper :company_sweeper

  def full_report
      #do stuff...
  end
end

The way I know it's not expiring is that the full report returns old data, and responds nearly instantaneously. Weird, right?

A: 

I don't think there are enough details here to really answer your question, but here are some questions:

The sweeper should fire independently from the full_report action, so if you make a change to a Company, you should see the debugger fire (which it looks like is happening correctly). You don't then need to run the full_report action, so at this point you could verify the cached file has been removed. It could be useful to step through expire_action in the debugger to see if rails is skipping the expiry for some other reason.


EDIT: oh you know what, I was just diggging into this, and it looks like expire_action is expected to run in a controller's context (I was reading the gem source in actionpack). It assumes 'self' is a controller, so your passing in the option :controller is being ignored.

Other examples give a specific string instead of options (e.g. expire_action '/reports/full_report') I don't like that personally---it's not using the router---but it seems like it would work.

Perhaps you should switch to that method, ensure it works, and then in the debugger see if you have access to url_for. it could be as simple as expire_action url_for(:controller => 'reports', :action => 'full_report')

joshsz
thanks for the tips...aside from what you asked me to do, what kind of additional information do you think might help us figure out the problem spot?
btelles
my comment couldn't fit! I've ammended my answer :)
joshsz
+3  A: 

Do you have a cache_sweeper declaration in your CompaniesController, too? The sweeper must be included in the controller that performs lifecycle actions on the model in question. Unless you do things with Company instances in ReportsController, the cache_sweeper line doesn't belong there.

Action caching includes an implicit host name. If the two hits are coming in on different host names, caching is done under one and expiration under a different one.

Steve Madsen
Congratulations Monsieur Madsen. The Cache sweeper was in fact in the wrong place. thanks for the tip!
btelles