Nested to_xml for awesome_nested_set

Posted by Daniel Wanja Tue, 19 Aug 2008 14:47:04 GMT

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.

<category>
  <created-at type="datetime">2008-08-18T14:46:07Z</created-at>
  <description nil="true"></description>
  <id type="integer">1</id>
  <lft type="integer">1</lft>
  <name>Main Category</name>
  <parent-id type="integer" nil="true"></parent-id>
  <qty-in-stock type="integer" nil="true"></qty-in-stock>
  <rgt type="integer">28</rgt>
  <updated-at type="datetime">2008-08-18T14:46:07Z</updated-at>
  <category>
    <created-at type="datetime">2008-08-18T14:46:07Z</created-at>
    <description nil="true"></description>
    <id type="integer">11</id>
    <lft type="integer">2</lft>
    <name>Dvds</name>
    <parent-id type="integer">1</parent-id>
    <qty-in-stock type="integer" nil="true"></qty-in-stock>
    <rgt type="integer">9</rgt>
    <updated-at type="datetime">2008-08-18T14:46:07Z</updated-at>
    <category>
      <created-at type="datetime">2008-08-18T14:46:07Z</created-at>
      <description nil="true"></description>
      <id type="integer">14</id>
      <lft type="integer">3</lft>
      <name>DVD</name>
      <parent-id type="integer">11</parent-id>
      <qty-in-stock type="integer">100</qty-in-stock>
      <rgt type="integer">4</rgt>
      <updated-at type="datetime">2008-08-18T14:46:07Z</updated-at>
    </category>
    <category>
      <created-at type="datetime">2008-08-18T14:46:07Z</created-at>
      <description nil="true"></description>
      <id type="integer">13</id>
      <lft type="integer">5</lft>
      <name>HD DVD</name>
      <parent-id type="integer">11</parent-id>
      <qty-in-stock type="integer">0</qty-in-stock>
      <rgt type="integer">6</rgt>
      <updated-at type="datetime">2008-08-18T14:46:07Z</updated-at>
    </category>
    <category>
      <created-at type="datetime">2008-08-18T14:46:07Z</created-at>
      <description nil="true"></description>
      <id type="integer">12</id>
      <lft type="integer">7</lft>
      <name>Blueray</name>
      <parent-id type="integer">11</parent-id>
      <qty-in-stock type="integer">10</qty-in-stock>
      <rgt type="integer">8</rgt>
      <updated-at type="datetime">2008-08-18T14:46:07Z</updated-at>
    </category>
  </category>
  <category>
    <created-at type="datetime">2008-08-18T14:46:07Z</created-at>
    <description nil="true"></description>
    <id type="integer">7</id>
    <lft type="integer">10</lft>
    <name>Cell Phones</name>
    <parent-id type="integer">1</parent-id>
    <qty-in-stock type="integer" nil="true"></qty-in-stock>
    <rgt type="integer">17</rgt>
    <updated-at type="datetime">2008-08-18T14:46:07Z</updated-at>
    <category>
      <created-at type="datetime">2008-08-18T14:46:07Z</created-at>
      <description nil="true"></description>
      <id type="integer">10</id>
      <lft type="integer">11</lft>
      <name>Prepaid Cards</name>
      <parent-id type="integer">7</parent-id>
      <qty-in-stock type="integer">3</qty-in-stock>
      <rgt type="integer">12</rgt>
      <updated-at type="datetime">2008-08-18T14:46:07Z</updated-at>
    </category>
    <category>
      <created-at type="datetime">2008-08-18T14:46:07Z</created-at>
      <description nil="true"></description>
      <id type="integer">9</id>
      <lft type="integer">13</lft>
      <name>Phones</name>
      <parent-id type="integer">7</parent-id>
      <qty-in-stock type="integer">20</qty-in-stock>
      <rgt type="integer">14</rgt>
      <updated-at type="datetime">2008-08-18T14:46:07Z</updated-at>
    </category>
    <category>
      <created-at type="datetime">2008-08-18T14:46:07Z</created-at>
      <description nil="true"></description>
      <id type="integer">8</id>
      <lft type="integer">15</lft>
      <name>Accessories</name>
      <parent-id type="integer">7</parent-id>
      <qty-in-stock type="integer">8</qty-in-stock>
      <rgt type="integer">16</rgt>
      <updated-at type="datetime">2008-08-18T14:46:07Z</updated-at>
    </category>
  </category>
  <category>
    <created-at type="datetime">2008-08-18T14:46:07Z</created-at>
    <description nil="true"></description>
    <id type="integer">2</id>
    <lft type="integer">18</lft>
    <name>Cameras &amp; Photo</name>
    <parent-id type="integer">1</parent-id>
    <qty-in-stock type="integer" nil="true"></qty-in-stock>
    <rgt type="integer">27</rgt>
    <updated-at type="datetime">2008-08-18T14:46:07Z</updated-at>
    <category>
      <created-at type="datetime">2008-08-18T14:46:07Z</created-at>
      <description nil="true"></description>
      <id type="integer">6</id>
      <lft type="integer">19</lft>
      <name>Digital Cameras</name>
      <parent-id type="integer">2</parent-id>
      <qty-in-stock type="integer">5</qty-in-stock>
      <rgt type="integer">20</rgt>
      <updated-at type="datetime">2008-08-18T14:46:07Z</updated-at>
    </category>
    <category>
      <created-at type="datetime">2008-08-18T14:46:07Z</created-at>
      <description nil="true"></description>
      <id type="integer">5</id>
      <lft type="integer">21</lft>
      <name>Analog Cameras</name>
      <parent-id type="integer">2</parent-id>
      <qty-in-stock type="integer">0</qty-in-stock>
      <rgt type="integer">22</rgt>
      <updated-at type="datetime">2008-08-18T14:46:07Z</updated-at>
    </category>
    <category>
      <created-at type="datetime">2008-08-18T14:46:07Z</created-at>
      <description nil="true"></description>
      <id type="integer">4</id>
      <lft type="integer">23</lft>
      <name>Accessories</name>
      <parent-id type="integer">2</parent-id>
      <qty-in-stock type="integer">12</qty-in-stock>
      <rgt type="integer">24</rgt>
      <updated-at type="datetime">2008-08-18T14:46:07Z</updated-at>
    </category>
    <category>
      <created-at type="datetime">2008-08-18T14:46:07Z</created-at>
      <description nil="true"></description>
      <id type="integer">3</id>
      <lft type="integer">25</lft>
      <name>Bags</name>
      <parent-id type="integer">2</parent-id>
      <qty-in-stock type="integer">2</qty-in-stock>
      <rgt type="integer">26</rgt>
      <updated-at type="datetime">2008-08-18T14:46:07Z</updated-at>
    </category>
  </category>
</category>

How do you deal with that situation?

Comments

Leave a response

Comments