문제

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 < 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
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top