views:

38

answers:

3

I've got a tiny model (let's call it "Node") that represents a tree-like structure. Each node contains only a name and a reference to its father:

class Node < ActiveRecord::Base
  validates_presence_of :name, :parent_id
end

The table isn't very big - less than 100 elements. It's updated rarely - in the last 4 months 20 new elements were added, in one occasion, by the site admin.

Yet it is used quite a lot on my application. Given its tree-like structure, on some occasions a request triggers more than 30 database hits (including ajax calls, which I use quite a lot).

I'd like to use some sort of caching in order to lower the database access - since the table is so small, I thought about caching all registers in memory.

Is this possible rails 2.3? Is there a better way to deal with this?

+2  A: 

Why don't you just load them all every time to avoid getting hit with multiple loads?

Here's a simple example:

before_filter :load_all_nodes

def load_all_nodes
  @nodes = Node.all.inject({ }) { |h, n| h[n.id] = n; n }
end

This will give you a hash indexed by Node#id so you can use this cache in place of a find call:

# Previously
@node = Node.find(params[:id])

# Now
@node = @nodes[params[:id].to_i]

For small, simple records, loading them in quickly in one fetch is a fairly inexpensive operation.

tadman
This is clever, so +1. However I was hoping for something a little more "raily". Like a built-in activerecord functionality or plugin. I'll keep looking.
egarcia
A: 

After looking in several places, I think tadman's solution is the simplest one.

For a more flexible solution, I've found this gist:

http://gist.github.com/72250/

Regards!

egarcia
+1  A: 

Have you looked at any of the plugins that give tree like behaviour.

Ryan Bates has a railscast on acts_as_tree however acts_as_nested_set or one of the other projects inspired by it such as awesome_nested_set or acts_as_better_nested_set may be better fits for your needs.

These projects allow you to get a node and all of its children with one sql query. The acts_as_better_nested_set site has a good description of how this method works.

Steve Weet
Hi Steve, I have, in fact. However I didn't like adding fields to my database - caching sounded better. But certainly your countribution might be useful to other people finding this question; +1 for you!
egarcia
@egarcia. Thanks. I agree that for this small dataset cacheing looks like the right solution. I'm using acts_as_nested_set for my company hierarchy and it's excellent.
Steve Weet