ruby-on-railsmodelobserver-patternsweeper

In Rails, a Sweeper isn't getting called in a Model-only setup


I'm working on a Rails app, where I'm using page caching to store static html output. The caching works fine. I'm having trouble expiring the caches, though.

I believe my problem is, in part, because I'm not expiring the cache from my controller. All of the actions necessary for this are being handled within the model. This seems like it should be doable, but all of the references to Model-based cache expiration that I'm finding seem to be out of date, or are otherwise not working.

In my environment.rb file, I'm calling

config.load_paths += %W( #{RAILS_ROOT}/app/sweepers )

And I have, in the /sweepers folder, a LinkSweeper file:

class LinkSweeper < ActionController::Caching::Sweeper
  observe Link

  def after_update(link)
    clear_links_cache(link)
  end

  def clear_links_cache(link)
  # expire_page :controller => 'links', :action => 'show', :md5 => link.md5
    expire_page '/l/'+ link.md5 + '.html'
  end
end

So ... why isn't it deleting the cached page when I update the model? (Process: using script/console, I'm selecting items from the database and saving them, but their corresponding pages aren't deleting from the cache), and I'm also calling the specific method in the Link model that would normally invoke the sweeper. Neither works.

If it matters, the cached file is an md5 hash off a key value in the Links table. The cached page is getting stored as something like /l/45ed4aade64d427...99919cba2bd90f.html.

Essentially, it seems as though the Sweeper isn't actually observing the Link. I also read (here) that it might be possible to simply add the sweeper to config.active_record.observers in environment.rb, but that didn't seem to do it (and I wasn't sure if the load_path of app/sweepers in environment.rb obviated that).


Solution

  • Just a note: you can use cache_sweeper in ApplicationController.

    class ApplicationController < ActionController::Base
      cache_sweeper :my_sweeper
    end
    
    class MySweeper < ActionController::Caching::Sweeper
      observe MyModel
    
      def after_update(my_model)
        expire_page(...)
      end
    end