Another Small RoR Tip 19

Posted by yrashk

While working on Frontcamp we’ve found that we need to cache some methods.

You can find out quick hack solution there

Simply insert

ActiveRecord::Base.extend Caches::ClassMethods

in your config/environment.rb and you will be able to specify


caches :method_name
or

caches :method_name, :timeout => 2.minutes

in your models.

Default timeout is 60 seconds.

What is important is that this solution caches calls with arguments. For example, if you will make a method_name(“Hello”) call you’ll get next method_name(“Hello”) cached, but method_name(“Bye”) will not be cached.

Also you will be able to invalidate cache explicitely with invalidate_method_name_cache and invalidate_all_method_name_caches calls.

Comments

Leave a response

  1. BrianJanuary 17, 2007 @ 05:56 PM

    Hi, does this work in Rails 1.2? I’m getting the following error when I try to use this:

    class StoryOrder < ActiveRecord::Base

    caches :fetch

    (eval):1:in `caches’: undefined method `fetch’ for class `StoryOrder’

    Any ideas? Thanks, Brian

  2. Yurii RashkovskiiJanuary 17, 2007 @ 07:53 PM

    Brian,

    First of all, consider installing latest version as a plugin:

    http://pad.verbdev.com/cachesrb/show/HowToGet

    Then, to cache method, it should already exist:

     
     class StoryOrder < ActiveRecord::Base
       def fetch
         ...
       end
    
       caches :fetch
     end
     
    
  3. MartinMarch 16, 2007 @ 08:58 PM

    I’m having the same problem. I can see the plugin is being loaded but I still get the undefined method error. Rails 1.2.2 with the trunk caches.rb.

    In the README what exactly do you mean by the line: “Simply do `BaseClass.extend Caches’ and you will be able to specify” ?

  4. Yurii RashkovskiiMarch 17, 2007 @ 02:35 AM

    Martin,

    In which class do you get “undefined method”. Are you using `caches’ in ActiveRecord model?

    I’ve just checked—it works just fine in 1.2.2 and trunk caches.rb.

    May be you’re trying to use it in a non-model class?

  5. MartinMarch 18, 2007 @ 11:39 AM

    Yurii, I’m an idiot. I was using it with controller methods. I was up too late that day :) Sorry..

  6. Yurii RashkovskiiMarch 18, 2007 @ 11:54 AM

    Martin,

    Actually you could use Caches.rb for controller. You just need to extend baseclass with Caches (just like it does for models at its initialization)

    Hope this helps.

  7. DallasMarch 25, 2007 @ 07:19 PM

    Is there a way to do static methods in my model?

  8. DallasMarch 26, 2007 @ 08:46 PM

    Yurri,

    I got non static methods working fine. Is there a different convention for caching a static method?

    Thanks for the plugin.

    Cheers, Dallas

  9. Yurii RashkovskiiMarch 27, 2007 @ 02:42 AM

    Dallas,

    Could you describe what do you want in a code?

    Yurii.

  10. DallasMarch 27, 2007 @ 08:22 PM

    When i tried this static method on team I get the following error

    (eval):1:in `caches’: undefined method `find_by_url_strings’ for class `Team’

    Thanks! Dallas

    class Team < ActiveRecord::Base ..... end

    1. find the team by it’s url string def self.find_by_url_strings(team_url, sport_url) self.find(:first, :conditions => [“teams.url_string=? AND sports.url_string=?”, team_url, sport_url], :include => [:team_aliases, :sport]) end
    caches :find_by_url_strings
     .....
  11. DallasMarch 28, 2007 @ 09:21 AM

    Sorry display formatted all wrong on that last post

  12. Yurii RashkovskiiMarch 31, 2007 @ 06:27 PM

    Dallas,

    Look here—http://rashkovskii.com/articles/2007/4/1/ongoing-improvements-in-caches-rb

    May be you find these changes useful.

  13. SteveJune 11, 2007 @ 12:55 PM

    This looks very good but it seems that pad.verbdev.com is down

  14. Yurii RashkovskiiJune 11, 2007 @ 12:59 PM

    Steve,

    true, forgot to re-add it after NS server change. Added it again, should be available soon, I think.

  15. DanielAugust 05, 2007 @ 06:11 AM

    Yuri,

    sorry to bother, but whenever I try checking out caches.rb (svn co svn://verbdev.com/rubylibs/caches.rb/trunk caches.rb) I get a “connection refused”-error.

    http://pad.verbdev.com/ is available, though.

    Cheers, Daniel

  16. Yurii RashkovskiiAugust 05, 2007 @ 06:15 AM

    Daniel,

    try this: http://svn.verbdev.com/rb/caches.rb/trunk

  17. DanielAugust 05, 2007 @ 06:28 AM

    Yuri,

    thanks! “svn co http://svn.verbdev.com/rb/caches.rb/trunk caches.rb” worked like a charm. Thumbs up for sharing and for your rapid response!

    Cheers, Daniel

  18. ShannonOctober 02, 2007 @ 01:41 PM

    Yuri,

    Thanks for the info! I have an issue with an app I created that comes up only on the FIRST request to a model after the app has been started.

    So, first request after start of model will trigger a error.

    Thereafter, the app works as intended.

    .... I get the feeling that the model in question is not “initialized” or properly loaded when the FIRST request hits it. After that, it responds without an error.

    Is there a way to initialize a model when a app loads? Any ideas are much appriceated.

    Thanks! Shannon

  19. NateNovember 08, 2007 @ 04:48 AM

    Yuri,

    We am seeing the same issue as Shannon. However we are using CTI

    http://wiki.rubyonrails.org/rails/pages/ClassTableInheritanceInRails

    Do you know if CTI affects rails caching?

    TIA, Nate

Comment