views:

75

answers:

4

I have this method in a controller:

def article_info
  if @article = Article.find_by_permalink(params[:permalink])
    @title = @article.title
    @description = @article.excerpt
    @body = @article.body
  else
    render_404
  end
end

I ultimately want to cache the results of Article.find_by_permalink so that query isn't executed every time an article is accessed.

So, how do I go about caching that query? Can I be cached from within the controller?

CLARIFICATION: I'm looking to cache this for an indefinite amount of time (until I decide to expire it). I'll ultimately be using memcache to do this.

A: 

Have you checked the log? Usually rails is pretty good at caching things by itself.

A cache database call is noted as such:

**CACHE (0.0ms)**   SELECT * FROM `funnels` WHERE bla bla

If it doesn't satisfy you, try looking at this tutorial on rails envy.

Of course if you do ...

@article = Article.find_by_permalink(params[:permalink])
@title = @article.title
@description = @article.excerpt
@body = @article.body

... only 1 database query is made. Calling @article will not reload the object.

marcgg
Added clarification to my post. I'm looking to cache this for an indefinite amount of time (until I decide to expire it). I'll ultimately be using memcache to do this.
Shpigford
Checkout the tutorial I put in my answer, it seems to me that it's what you're looking for
marcgg
A: 

This was covered in Railscasts episode 115: Caching in Rails 2.1.

John Topley
A: 

You don't cache model objects in the controller, you cache them in the model.

Dustin
A: 

You could define a new method in your model as described here:

# models/article.rb
def self.all_cached
  Rails.cache.fetch('Article.all') { all }
end

Then your calls to Article.all_cached would not query the database if the result is cached. Otherwise it would fetch the result from the database.

Update: Your find_by_permalink call could be replaced with cached_find_by_permalink:

# models/article.rb
def self.cached_find_by_permalink(permalink)
  Rails.cache.fetch('Article.find_by_permalink.' + permalink) do
    find_by_permalink(permalink)
  end
end
Tomas Markauskas