unorganized.net directly from the brain of Eike Bernhardt

28Oct/110

Mongoid Cache Sweeper

I just needed to add a Cache Sweeper in a Rails 3.1 app for a Mongoid model.

Using a ActionController::Caching::Sweeper didn’t run for updates on the models (even though it should work for non-Mongoid-models), so I ended up using a Mongoid::Observer to invalidate the cache when a model was updated.

To seperate the observers from the models, I created a app/observers directory and used the following code to automatically load the observers:

# mongoid observers/sweepers
config.mongoid.observers = Dir["#{config.root}/app/observers/*.rb"].collect do |full_name|
  File.basename(full_name,'.rb').to_sym
end

This is the app/observers/city_observer.rb file:

class CityObserver < Mongoid::Observer
  def after_create(city)
    expire_cache_for(city)
  end

  def after_update(city)
    expire_cache_for(city)
  end

  def after_destroy(city)
    expire_cache_for(city)
  end

  private

  def expire_cache_for(city)
    # expire fragments/pages for city
    @c ||= ActionController::Base.new

    @c.expire_fragment("city_#{city.id.to_s}")
    if city.state.present?
      @c.expire_fragment("state_#{city.state.id.to_s}")
    end
    if city.country.present?
      @c.expire_fragment("country_#{city.country.id.to_s}")
    end

    # and expire the continent page cache
    @c.expire_page("/continents/#{city.country.continent.slug}")
  end
end

Since the expire_fragment/expire_page functions are not defined in the observer, I create a ActionController::Base object to call them on that.

With this, a model update expires cached pages

11Apr/060

Ruby on Rails: serialize

Da ich inzwischen immer mehr mit Ruby on Rails arbeite, brauch ich auch hier mal wieder ne Sammelstelle für gute Tips und Ideen .. und Sachen die ich praktisch finde.

Los gehts mit “:serialize”:


class User < ActiveRecord::Base
serialize :preferences
end
user = User.create(:preferences) => { "details" => "full", "stylesheet" => "old" })
User.find(user.id).preferences # => { "details" => "full", "stylesheet" => "old" }

Und mit diesem bischen Code kann man ohne Probleme Arrays oder Hashes oder was man will in User.preferences speichern, für den Programmierer ist es völlig transparent, die komplette “Arbeit” wird einem von RoR abgenommen. Sehr praktisch!