Emmanuel Orozco Emmanuel Orozco - 4 months ago 15
Ruby Question

Move object to a parent object in ruby

I have an array of objects like this:

[
{
"id": 2,
"title": "LA COPA",
"parent_menu_id": nil
},
{
"id": 3,
"title": "CALENDARIO",
"parent_menu_id": nil
},
{
"id": 5,
"title": "Torneo",
"parent_menu_id": 2
},
{
"id": 6,
"title": "Nice",
"parent_menu_id": 2
}
]


This is the structure of a menu.

Each object is an menu item.

If the key "parent_menu_id" is nil, it means that the item is a parent menu.

If it has a value, is a children. I.E the third item means that item id: 5 is child of item id:2.

This is the desired output:

[
{
"id": 2,
"title": "LA COPA",
"active": true,
"parent_menu_id": nil,
"submenus":[
{
"id": 5,
"title": "Torneo",
"active": true,
"parent_menu_id": 2
},
{
"id": 6,
"title": "Nice",
"parent_menu_id": 2
}
]
},
{
"id": 3,
"title": "CALENDARIO",
"active": true,
"parent_menu_id": nil
}
]


I know the algorithm:


  1. if pareny_menu_id is different than nill search the key id == parent_menu_id

  2. If submenu key is not present, create it.

  3. Move the child item to the parent.

  4. Then delete the child item from base location.



But I am not sure about the methods to use..

Any ideas?

Cheers!

Answer
#!ruby

require 'pp'

objects = [
  {
    "id"             => 2,
    "title"          => "LA COPA",
    "parent_menu_id" => nil
  },
  {
    "id"             => 3,
    "title"          => "CALENDARIO",
    "parent_menu_id" => nil
  },
  {
    "id"             => 5,
    "title"          => "Torneo",
    "parent_menu_id" => 2
  },
  {
    "id"             => 6,
    "title"          => "Nice",
    "parent_menu_id" => 2
  }
]

objects.collect! do |child|
  if not child["parent_menu_id"].nil? then
    parents = objects.select{|o| o["id"] == child["parent_menu_id"]}
    parents.each do |pr|
      pr["submenus"] ||= []
      pr["submenus"] << child
    end
  end
  child
end.select!{|o| o["parent_menu_id"].nil? }
pp objects

output:

[{"id"=>2,
  "title"=>"LA COPA",
  "parent_menu_id"=>nil,
  "submenus"=>
   [{"id"=>5, "title"=>"Torneo", "parent_menu_id"=>2},
    {"id"=>6, "title"=>"Nice", "parent_menu_id"=>2}]},
 {"id"=>3, "title"=>"CALENDARIO", "parent_menu_id"=>nil}]