Rails 3: Sweeper not destroying fragments, thinks caching was disabled
I want to expire fragments with a sweeper. The sweeper callbacks are executed, but the calls to expire_fragment do nothing, because (I assume) cache_configured? returns nil. Caching is configured and fragments are being created and used in my templates (verified it in the logs). What am I doing wrong?
application.rb
config.cache_store = :mem_cache_store, "XXX.XXX.XXX.XXX", { # I use a real IP
:compress => true,
:namespace => "#{Rails.env}_r3"
}
config.active_record.observers = [:auction_sweeper, :address_sweeper]
production.rb
config.action_controller.perform_caching = true
auction_sweeper.rb
class AuctionSweeper <开发者_StackOverflow; ActionController::Caching::Sweeper
observe Auction
def after_create(auction)
Rails.logger.info "AuctionSweeper.expire_details #{auction.id} #{cache_configured?.inspect}=#{perform_caching.inspect}&&#{cache_store.inspect}"
expire_fragment("auction/#{auction.reference_sid}")
end
end
In log files, cache_configured? is nil and so is perform_caching and cache_store.
AuctionSweeper.expire_details 12732 nil=nil&&nil
So I assume, that my fragments are not expired because the code of expire_fragment reads:
File actionpack/lib/action_controller/caching/fragments.rb, line 87
87: def expire_fragment(key, options = nil)
88: return unless cache_configured?
I found a solution (hack?) here that suggests to set @controller and it works for me.
class AuctionSweeper < ActionController::Caching::Sweeper
observe Auction
def after_create(auction)
@controller ||= ActionController::Base.new
Rails.logger.info "AuctionSweeper.expire_details #{auction.id} #{cache_configured?.inspect}=#{perform_caching.inspect}&&#{cache_store.inspect}"
expire_fragment("auction/#{auction.reference_sid}")
end
end
Also a note to myself: remember to return true from before filters also in sweepers or you get ActiveRecord::RecordNotSaved and wonder why.
You didn't share your Rails.env
- caching is naturally disabled in development
and test
- maybe you missed something?
Instead of setting the instance variable for the controller I use an initializer called cache_sweeping_observer.rb
class CacheSweepingObserver < ActiveRecord::Observer
include ActiveSupport::Configurable
include ActionController::Caching
config_accessor :perform_caching
class << self
def config
ActionController::Base.config
end
end
end
Then I inherit from it for any observer that is for sweeping caches.
class ModelSweeper < CacheSweepingObserver
observe Model
def after_update(model)
expire_fragment "#{model.id}"
true
end
end
精彩评论