devroom.io/content/posts/2008-04-09-rails-snippet-caching-expensive-calls.md

43 lines
1.4 KiB
Markdown
Raw Normal View History

2015-03-26 11:28:08 +00:00
+++
date = "2008-04-09"
title = "Rails Snippet: Caching expensive calls"
tags = ["General", "RubyOnRails", "Ruby", "Rails", "snippet"]
slug = "rails-snippet-caching-expensive-calls"
+++
In Rails, from time to time, you may encounter you have a method you call several times, but which returns always the same result. For example, have the following:
2017-03-20 15:35:19 +00:00
``` ruby
class Person < ActiveRecord::Base
2015-03-26 11:28:08 +00:00
has_many :articles
def get_approved_articles
self.articles.find(:all, :conditions => {:approved => true}, :order => 'approved_on DESC')
end
2017-03-20 15:35:19 +00:00
end
```
2015-03-26 11:28:08 +00:00
A query is fired every time you call Person#get_approved_articles. To cache the result of the query during this request, just add a bit of magic
2017-03-20 15:35:19 +00:00
``` ruby
class Person < ActiveRecord::Base
2015-03-26 11:28:08 +00:00
has_many :articles
def get_approved_articles
@approved_articles ||= self.articles.find(:all, :conditions => {:approved => true}, :order => 'approved_on DESC')
end
2017-03-20 15:35:19 +00:00
end
```
2015-03-26 11:28:08 +00:00
This will return the @approved_articles value if it exists. If it doesn't, which is the first time you access the method, the query is run and stored in @approved_articles for later use.
Note: I know it's much easier to define this kind of behaviour, but it's just an illustration.
2017-03-20 15:35:19 +00:00
``` ruby
class Person < ActiveRecord::Base
2015-03-26 11:28:08 +00:00
has_many :articles
has_many :approved_articles, :class_name => "Article", :conditions => {:approved => true}, :order => 'approved_on DESC'
2017-03-20 15:35:19 +00:00
end
```
2015-03-26 11:28:08 +00:00