onrails.org home

Nested to_xml for awesome_nested_set

I was updating an example build using the better_nested_set to use the awesome_nested_set. One thing that I didn’t find in awesome_nested_set are some helper methods that are returning a full tree of the nested set as one XML document. With better nested set I could do

Category.result_to_attributes_xml(Category.root.ancestors)

So I have added the following full_xml method to my nested active record to recurse all the children. Note that the full_method calls the full_method on the children passing along the xml builder that is created by the to_xml method and passed as the xml variable to block, thus building a nested XML document.

class Category < ActiveRecord::Base
belongs_to :parent, :class_name => “Category”
acts_as_nested_set

def full_xml(builder=nil) to_xml(:builder => builder, :skip_instruct => true) do |xml| children.each { |child| child.full_xml(xml) } end end

end

Obviously it would be nice that the awesome_nested_set provides such a method.

So let’s assume I create the following nested structure:

Category.transaction do
root = Category.create(:name => “Main Category”)

cameras = Category.create(:name => “Cameras & Photo”) cameras.move_to_child_of(root) Category.create(:name => “Bags”, :qty_in_stock => 2).move_to_child_of(cameras) Category.create(:name => “Accessories”, :qty_in_stock => 12).move_to_child_of(cameras) Category.create(:name => “Analog Cameras”, :qty_in_stock => 0).move_to_child_of(cameras) Category.create(:name => “Digital Cameras”, :qty_in_stock => 5).move_to_child_of(cameras) phones = Category.create(:name => “Cell Phones”) phones.move_to_child_of(root) Category.create(:name => “Accessories”, :qty_in_stock => 8).move_to_child_of(phones) Category.create(:name => “Phones”, :qty_in_stock => 20).move_to_child_of(phones) Category.create(:name => “Prepaid Cards”, :qty_in_stock => 3).move_to_child_of(phones) dvds = Category.create(:name => “Dvds”) dvds.move_to_child_of(root) Category.create(:name => “Blueray”, :qty_in_stock => 10).move_to_child_of(dvds) Category.create(:name => “HD DVD”, :qty_in_stock => 0).move_to_child_of(dvds) Category.create(:name => “DVD”, :qty_in_stock => 100).move_to_child_of(dvds)

end

I can now get the whole nested structure in one go:

Category.roots.first.full_xml

And get the following XML in return.

<typo:code lang=“xml>

”datetime">2008-08-18T14:46:07Z

1
1
Main Category


28
2008-08-18T14:46:07Z

2008-08-18T14:46:07Z

11
2
Dvds
1

9
2008-08-18T14:46:07Z

2008-08-18T14:46:07Z

14
3
DVD
11
100
4
2008-08-18T14:46:07Z

2008-08-18T14:46:07Z 13 5 HD DVD 11 0 6 2008-08-18T14:46:07Z 2008-08-18T14:46:07Z 12 7 Blueray 11 10 8 2008-08-18T14:46:07Z 2008-08-18T14:46:07Z 7 10 Cell Phones 1 17 2008-08-18T14:46:07Z 2008-08-18T14:46:07Z 10 11 Prepaid Cards 7 3 12 2008-08-18T14:46:07Z 2008-08-18T14:46:07Z 9 13 Phones 7 20 14 2008-08-18T14:46:07Z 2008-08-18T14:46:07Z 8 15 Accessories 7 8 16 2008-08-18T14:46:07Z 2008-08-18T14:46:07Z 2 18 Cameras & Photo 1 27 2008-08-18T14:46:07Z 2008-08-18T14:46:07Z 6 19 Digital Cameras 2 5 20 2008-08-18T14:46:07Z 2008-08-18T14:46:07Z 5 21 Analog Cameras 2 0 22 2008-08-18T14:46:07Z 2008-08-18T14:46:07Z 4 23 Accessories 2 12 24 2008-08-18T14:46:07Z 2008-08-18T14:46:07Z 3 25 Bags 2 2 26 2008-08-18T14:46:07Z

How do you deal with that situation?

Fork me on GitHub