How to generate json tree from pedigree

I use the pedigree to create a goal tree. I would like to send the contents of this tree to the browser using json.

My controller looks like this:

@goals = Goal.arrange respond_to do |format| format.html # index.html.erb format.xml { render :xml => @goals } format.json { render :json => @goals} end 

When I open the json file, I get this output:

 {"#<Goal:0x7f8664332088>":{"#<Goal:0x7f86643313b8>":{"#<Goal:0x7f8664331048>":{"#<Goal:0x7f8664330c10>":{}},"#<Goal:0x7f8664330e68>":{}},"#<Goal:0x7f86643311b0>":{}},"#<Goal:0x7f8664331f70>":{},"#<Goal:0x7f8664331d18>":{},"#<Goal:0x7f8664331bd8>":{},"#<Goal:0x7f8664331a20>":{},"#<Goal:0x7f86643318e0>":{},"#<Goal:0x7f8664331750>":{},"#<Goal:0x7f8664331548>":{"#<Goal:0x7f8664330aa8>":{}}} 

How can I render the contents of Goal objects in a json file?

I tried this:

 @goals.map! {|goal| {:id => goal.id.to_s} 

but it does not work since @goals is an ordered hash.

+8
json ruby-on-rails-3 ancestry
source share
3 answers

I got some help from tejo user at https://github.com/stefankroes/ancestry/issues/82 .

The solution is to put this method in the target model:

 def self.json_tree(nodes) nodes.map do |node, sub_nodes| {:name => node.name, :id => node.id, :children => Goal.json_tree(sub_nodes).compact} end end 

and then make the controller like this:

 @goals = Goal.arrange respond_to do |format| format.html # index.html.erb format.xml { render :xml => @goals } format.json { render :json => Goal.json_tree(@goals)} end 
+10
source share

Inspired from this https://github.com/stefankroes/ancestry/wiki/arrange_as_array

 def self.arrange_as_json(options={}, hash=nil) hash ||= arrange(options) arr = [] hash.each do |node, children| branch = {id: node.id, name: node.name} branch[:children] = arrange_as_json(options, children) unless children.empty? arr << branch end arr end 
+2
source share

I ran into this problem the other day (ancestry 2.0.0). I changed Johan's answer to my needs. I have three models using ancestors, so it makes sense to extend OrderedHash to add the as_json method instead of adding json_tree to the three models.

Since this thread was so useful, I thought I would share this modification.

Install this as a module or monkey patch for ActiveSupport :: OrderedHash

 def as_json(options = {}) self.map do |k,v| x = k.as_json(options) x["children"] = v.as_json(options) x end end 

We invoke the model and use its default json behavior. Not sure. If I have to call before _json or like _json. I used as_json here and it works in my code.

In the controller

 ... format.json { render :json => @goal.arrange} ... 
0
source share

All Articles