views:

455

answers:

3

Hi, Everyone

I am working on a custom accessor method like an example below:

class Forest < ActiveRecord : Base
  has_many :trees

  def total_water_usage
    # summarize each tree's water_usage in this forest.
    # return as string 
  end

end

class Tree < ActiveRecord : Base
  belongs_to :forest

end

That is, I need your help for 2 questions:

  1. How can I access each tree just for an instance of Forest class. (Like example below, the total water usage shouldn't summarize another forest's tree)

    asiaForest = Forest.find_by_name( 'asia' )
    asiaForest.total_water_usage
    
  2. How can I force this method to be rendered by to_xml method? for example, I think the result should be similar to this:

    asiaForest.to_xml
    <asiaForest>
       ...
       <total_water_usage>239000</total_water_usage>   
       ...
    </asiaForest>
    

Could you help me to do this?

+3  A: 

records.to_xml(:methods => :total_water_usage)

Ryan Bigg
+1. Simple and clear.
Swanand
A: 

The answers are as follows:

class Forest < ActiveRecord::Base
  has_many :trees

  def total_water_usage
    trees.sum(:water_usage)
  end

  def to_xml
    attributes["total_water_usage"] = total_water_usage
    attributes.to_xml({:root => self.class.element_name})
  end
end

class Tree < ActiveRecord::Base
  belongs_to :forest

  def water_usage
    # place your water usage calculation for a tree here
  end
end

Explanation: Part 1 of the question is answered in total_water_usage which will call water_usage in each trees and sum it.

Part 2 we have to override the to_xml method to include the total_water_usage key. Taken from the original to_xml method.

SamChandra
A: 

To implement on a global model scale you could add this to your model file.

 alias_method :ar_to_xml, :to_xml

  def time_zone_offset
       get_my_time_zone_offset_or_something
  end

  def to_xml(options = {}, &block)
    default_options = { :methods => [ :time_zone_offset ]}
    self.ar_to_xml(options.merge(default_options), &block)
  end