2

Good morning,

A bit of background might help. I'm creating a very simple app to be used as an attendance tracking solution - it will sit on a running computer in a gym, and people can enter their names and click a button based on what type of workout they did.

The people running the app are not overly technical - but I wanted to give them a way to change the basic text on the home page, as well as on the 'help' page. I created a Meta model which has columns for "help text" "main page text" etc., which they can update via the ActiveAdmin interface.

I want to do page caching on both the home and help pages (more so just to learn Rails caching for my own more complicated projects) and only want to expire the 'help' page if the Meta -> "help_text" attribute has changed, but expire the home page if any of the other Meta -> attributes have changed.

Is this possible?

My caching code is pretty basic at this point:

class MetaSweeper < ActionController::Caching::Sweeper
  observe Meta

  def after_create(meta)
    expire_cache_for(meta)
    puts "[CACHE] Expiring cached pages"
  end

  def after_update(meta)
    expire_cache_for(meta)
    puts "[CACHE] Expiring cached pages"
  end

  def after_destroy(meta)
    expire_cache_for(meta)
    puts "[CACHE] Expiring cached pages"
  end

  private
  def expire_cache_for(meta)
    expire_page(:controller => 'static_pages', :action => 'home')
    expire_page(:controller => 'static_pages', :action => 'help')

    # Expire a fragment
    #expire_fragment('all_available_products')
  end
end

And in the application_controller:

cache_sweeper :meta_sweeper

Thanks!

EDIT 1

From the first answer, I've tried to set a virtual attribute on the "Meta" model to try to capture if the help_content attribute has changed, so that I can determine if I should expire the /help page.

meta.rb

attr_accessor :help_changed
before_update :set_cache_expiry_checker

private

  def set_cache_expiry_checker
    help_changed = "you bet its changed!"
  end

meta_sweeper.rb

def after_update(meta)
  puts "should be doing something here about expiring...."      

  if meta.help_changed
    puts "should expire help page" 
  else
    puts "should NOT expire help page"  
  end

When I run my application, I see the output of the first puts, but not the second. meta.help_changed appears to be nil.... even though I do have the virtual attribute on the model. If I do a "puts meta.inspect" at the top of after_update, I see all of the meta attributes EXCEPT the virtual one. Is there something going on in sweepers that only pulls the database stuff?

Is there another place inside the sweeper I can set a variable to do this? I've tried doing a:

expire_help_cache = meta.help_changed

At the very top of meta_sweeper.rb, but that throws errors as there is no "meta" variable when you are outside of the after_update method.

Brandon
  • 3,091
  • 2
  • 34
  • 64
  • Change that to self.help_changed - you're setting a local variable at the moment, not an instance variable. – Frederick Cheung Apr 07 '12 at 16:48
  • Man... you'd think with my morning coffee I would have already picked that one up. I'll play around a bit more, seem to be getting some odd error out of active admin: 'NoMethodError (undefined method `metum_url' for #):' – Brandon Apr 07 '12 at 17:03
  • where you created sweeper and how to create sweeper can you explain to me plz? – Giridharan Oct 01 '19 at 07:52

1 Answers1

2

Rails provides you with afoo_changed? method that tells you if the foo attribute has changed and a changes method that lists all the changes. By the time your sweeper is called I suspect these will have already been reset.

You could however add a before_update callback that would check whether the columns you are interested in are dirty. Set an instance variable based on that and then check the value of the instance variable in your sweeper.

Frederick Cheung
  • 83,189
  • 8
  • 152
  • 174
  • Hmmm... I can't seem to get it working... Not sure if it is something I'm doing wrong... I'll add what I've tried to my question. – Brandon Apr 07 '12 at 16:41
  • Frederick - your solution works - I'm accepting your answer. The issue mentioned above is something funky to do with ActiveAdmin and 'false'boolean attributes. However - I'm still having issues getting the caching to work, but thought it belonged in a separate question. see [my question here](http://stackoverflow.com/questions/10056829/rails-activeadmin-page-action-caching-calls-wrong-controller) Thanks for your help!! – Brandon Apr 07 '12 at 17:50
  • Never mind. That question had been asked & answered, I was just not looking for the right keywords. Answer [here](http://stackoverflow.com/questions/5082181/rails-caching-expire-action-in-another-namespace) . Thanks for all your help Frederick – Brandon Apr 07 '12 at 18:04