4

We have the following sweeper in a rails application:

class AgencyEquipmentTypeSweeper < ActionController::Caching::Sweeper 
  observe AgencyEquipmentType

  #include ExpireOptions
  def after_update(agency_equipment_type)
    expire_options(agency_equipment_type)
  end

  def after_delete(agency_equipment_type)
    expire_options(agency_equipment_type)
  end

  def after_create(agency_equipment_type)
    expire_options(agency_equipment_type)
  end

  def expire_options(agency_equipment_type)
    Rails.cache.delete("agency_equipment_type_options/#{agency_equipment_type.agency_id}")
  end
end

We'd like to extract the after_update, after_delete, and after_create callbacks to a module called "ExpireOptions"

The module should look like this (with the 'expire_options' method staying behind in the original sweeper):

module ExpireOptions
  def after_update(record)
    expire_options(record)
  end

  def after_delete(record)
    expire_options(record)
  end

  def after_create(record)
    expire_options(record)
  end
end

class AgencyEquipmentTypeSweeper < ActionController::Caching::Sweeper 
  observe AgencyEquipmentType

  include ExpireOptions

  def expire_options(agency_equipment_type)
    Rails.cache.delete("agency_equipment_type_options/#{agency_equipment_type.agency_id}")
  end
end

BUT the cache expirations only work if we define the methods explicitly inside the sweeper. Is there an easy way to extract those callback methods to a module, and still have them work?

btelles
  • 5,390
  • 7
  • 46
  • 78
  • 1
    That's very odd. Both examples work locally for me. What are you using for your cache store? – Jack Chu May 25 '11 at 07:08
  • 1
    it should work with your current code. no changes needed. include statement takes care of everything. – Anand May 27 '11 at 10:12
  • Do the module based methods after_create, etc. get called at all? – moritz May 31 '11 at 17:56
  • 1
    Seconded that the code works locally here - is anything not mentioned configured in any exceptionally non-standard ways? More code via a bin link? – Abba Bryant May 31 '11 at 21:32
  • Darn. Once I used memcached -vvv, I saw that it was in fact caching as expected. %#*%@#*$^#(@...there goes 300 points I'll never get back. – btelles Jun 02 '11 at 13:30
  • @lakshman or @Jack Chu, If you'd like to formalize your comment into an answer, I'd be happy to award you the 300 points. – btelles Jun 02 '11 at 13:31

2 Answers2

2

Try with:

module ExpireOptions
  def self.included(base)
    base.class_eval do
      after_update :custom_after_update
      after_delete :custom_after_delete
      after_create :custom_after_create
    end
  end

  def custom_after_update(record)
    expire_options(record)
  end

  def custom_after_delete(record)
    expire_options(record)
  end

  def custom_after_create(record)
    expire_options(record)
  end
end
Pablo Castellazzi
  • 4,164
  • 23
  • 20
0

I would try something like:

module ExpireOptions
  def after_update(record)
    self.send(:expire_options, record)
  end

  def after_delete(record)
    self.send(:expire_options, record)
  end

  def after_create(record)
    self.send(:expire_options, record)
  end
end

This should make sure it does not try to call those methods on the module, but on self which would hopefully be the calling object.

Does that help?

nathanvda
  • 49,707
  • 13
  • 117
  • 139