views:

295

answers:

1

Given the following ActiveRecord models:

class Tree < ActiveRecord::Base
  # attributes: title, price, some_date
  has_many :nodes
end

class Node < ActiveRecord::Base
  # attributes: title, price, some_date
  belongs_to :tree
end

A Tree has many nodes (1'000 - 2'000). For performance and other reasons I'd like to cache the price attribute in the Node instances. A node should always have the same price like its associated tree. Which would make calculations and querying easier and faster.

Are there any best practices on how to do this? Maybe even plugins?

What I've come up so far is:

class Tree
  after_save do; nodes.each{|n| n.update_attribute :price, price} if price_changed?; end
end

This can become a bit cumbersome overtime, as I need many such cached attributes.

+1  A: 

The problem with your solution seems to be that it will execute an UPDATE statement for each node. This can be made much more efficient with a single UPDATE SQL statement across all nodes of a tree.

In Rails, this can be done by

class Tree
  after_save do; nodes.update_all("price = #{price}") if price_changed?; end
end

See: http://api.rubyonrails.org/classes/ActiveRecord/Base.html#M002273

Note: A drawback of this approach is it won't trigger ActiveRecord callbacks on the nodes.

DanSingerman