John Bachir
John Bachir

Reputation: 22711

Why do cache sweepers need to be declared in controllers?

A cache sweeper is an observer with some hooks on the model it is observing:

class MySweeper < ActionController::Caching::Sweeper
  observe MyModel

  def after_update(my_model)
    expire_page(...)
  end
end

But documentation and guides also say to declare the sweeper in the controller:

class ApplicationController < ActionController::Base
  cache_sweeper :my_sweeper
end

Why is this? Isn't the point of an observer that it observers the model and takes action? Shouldn't the controller not have to be aware of when the cache is expiring or what is causing it?

clarification

my understanding of setting up the sweeper to be an observer is that it means "in all cases, when a MyModel is updated, run this cleanup code"

  1. Is that accurate?
  2. If so, then why does cache_sweeper :my_sweeper also need to be declared in a controller? What does that do?

Upvotes: 3

Views: 899

Answers (1)

cutalion
cutalion

Reputation: 4394

From the cache sweeper docs:

Sweepers are the terminators of the caching world and responsible for expiring caches when model objects change.

They do this by being half-observers, half-filters and implementing callbacks for both roles.

Sweeper uses controller to expire cache, to get caching settings, etc. Take a look at the source code. So, cache sweepers allow us to control cache from the controller side. And I think this is good, because we can expire cache on any event - change in the DB or user sign in, or anything else.

I think, if you don't want to call cache_sweeper method in the controllers, you can define controller method in your sweeper. I didn't test following code, but it should work, because I do the same thing in my sweeper specs.

class MySweeper < ActionController::Caching::Sweeper
  observe MyModel

  def after_update(my_model)
    expire_page(...)
  end

  def controller
    @controller ||= ActionController::Base.new
  end
end

Upvotes: 1

Related Questions