{"id":695,"date":"2011-10-28T13:32:37","date_gmt":"2011-10-28T11:32:37","guid":{"rendered":"http:\/\/unorganized.net\/blog\/?p=695"},"modified":"2011-12-16T09:34:08","modified_gmt":"2011-12-16T08:34:08","slug":"mongoid-cache-sweeper","status":"publish","type":"post","link":"https:\/\/unorganized.net\/blog\/2011\/10\/28\/mongoid-cache-sweeper\/","title":{"rendered":"Mongoid Cache Sweeper"},"content":{"rendered":"<p>I just needed to add a Cache Sweeper in a Rails 3.1 app for a <a href=\"http:\/\/mongoid.org\/\">Mongoid<\/a>\u00a0model.<\/p>\n<p>Using a\u00a0<a href=\"http:\/\/guides.rubyonrails.org\/caching_with_rails.html#sweepers\">ActionController::Caching::Sweeper<\/a>\u00a0didn&#8217;t run for updates on the models (even though it should work for non-Mongoid-models), so I ended up using a\u00a0<a href=\"http:\/\/mongoid.org\/docs\/callbacks\/observers.html\">Mongoid::Observer<\/a>\u00a0to invalidate the cache when a model was updated.<\/p>\n<p>To seperate the observers from the models, I created a <code>app\/observers<\/code> directory and used the following code to automatically load the observers:<\/p>\n<pre class=\"brush: rails; gutter: true\"># mongoid observers\/sweepers\r\nconfig.mongoid.observers = Dir[&quot;#{config.root}\/app\/observers\/*.rb&quot;].collect do |full_name|\r\n  File.basename(full_name,&#039;.rb&#039;).to_sym\r\nend<\/pre>\n<p>This is the <code>app\/observers\/city_observer.rb<\/code> file:<\/p>\n<pre class=\"brush: rails; gutter: true\">class CityObserver &lt; Mongoid::Observer\r\n  def after_create(city)\r\n    expire_cache_for(city)\r\n  end\r\n\r\n  def after_update(city)\r\n    expire_cache_for(city)\r\n  end\r\n\r\n  def after_destroy(city)\r\n    expire_cache_for(city)\r\n  end\r\n\r\n  private\r\n\r\n  def expire_cache_for(city)\r\n    # expire fragments\/pages for city\r\n    @c ||= ActionController::Base.new\r\n\r\n    @c.expire_fragment(&quot;city_#{city.id.to_s}&quot;)\r\n    if city.state.present?\r\n      @c.expire_fragment(&quot;state_#{city.state.id.to_s}&quot;)\r\n    end\r\n    if city.country.present?\r\n      @c.expire_fragment(&quot;country_#{city.country.id.to_s}&quot;)\r\n    end\r\n\r\n    # and expire the continent page cache\r\n    @c.expire_page(&quot;\/continents\/#{city.country.continent.slug}&quot;)\r\n  end\r\nend<\/pre>\n<p lang=\"ruby\">Since the <code>expire_fragment<\/code>\/<code>expire_page<\/code> functions are not defined in the observer, I create a <code>ActionController::Base<\/code> object to call them on that.<\/p>\n<p lang=\"ruby\">With this, a model update expires cached pages<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I just needed to add a Cache Sweeper in a Rails 3.1 app for a Mongoid\u00a0model. Using a\u00a0ActionController::Caching::Sweeper\u00a0didn&#8217;t run for updates on the models (even though it should work for non-Mongoid-models), so I ended up using a\u00a0Mongoid::Observer\u00a0to invalidate the cache when a model was updated. To seperate the observers from the models, I created a [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,10],"tags":[16,15,17,14],"class_list":["post-695","post","type-post","status-publish","format-standard","hentry","category-computers","category-ruby-on-rails","tag-cache","tag-mongoid","tag-observer","tag-rails"],"_links":{"self":[{"href":"https:\/\/unorganized.net\/blog\/wp-json\/wp\/v2\/posts\/695","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/unorganized.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unorganized.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unorganized.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unorganized.net\/blog\/wp-json\/wp\/v2\/comments?post=695"}],"version-history":[{"count":5,"href":"https:\/\/unorganized.net\/blog\/wp-json\/wp\/v2\/posts\/695\/revisions"}],"predecessor-version":[{"id":772,"href":"https:\/\/unorganized.net\/blog\/wp-json\/wp\/v2\/posts\/695\/revisions\/772"}],"wp:attachment":[{"href":"https:\/\/unorganized.net\/blog\/wp-json\/wp\/v2\/media?parent=695"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unorganized.net\/blog\/wp-json\/wp\/v2\/categories?post=695"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unorganized.net\/blog\/wp-json\/wp\/v2\/tags?post=695"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}