2012-03-30 14 views
8

Używam przodków, aby drzewo celów. Chciałbym wysłać zawartość tego drzewa do przeglądarki za pomocą json.Jak wygenerować drzewo json z przodków

Moje kontroler jest tak:

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

Gdy otwieram plik json, otrzymuję ten wynik:

{"#<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>":{}}} 

Jak mogę uczynić treść cel obiektów w json plik?

Próbowałem to:

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

ale to nie działa, ponieważ @goals jest uporządkowanym hash.

+1

Jeśli kod formatu jako kod (tiret przez 4 spacji lub otoczyć backticks [ '\']) nie trzeba losowo usunąć '<' and '>' s. http://stackoverflow.com/editing-help –

+0

Dziękuję. Naprawione. –

Odpowiedz

10

Dostałem pomoc od użytkownika tejo pod numerem https://github.com/stefankroes/ancestry/issues/82.

Rozwiązaniem jest wprowadzenie tej metody w modelu cel:

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 

a następnie dokonać wygląd kontrolera takiego:

@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 
+2

Wygląda na to, że nie potrzebujesz przodków, a następnie – SET

+1

. Czy jestem jedynym, który otrzymuje wiadomość w dziennikach? 'N + 1 Zapytanie wykryte Katalog => [: dzieci] Dodaj do wyszukiwarki:: obejmuje => [: dzieci] N + 1 Stos wywołań zapytania zapytania' Używam 'closure_tree'. – cantonic

2

zainspirowana tym 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 
0

Wpadłem na ten problem na drugi dzień (pochodzenie 2.0.0). Zmieniłem odpowiedź Johana na moje potrzeby. Mam trzy modele korzystające z przodków, więc sensownym było rozszerzenie OrderedHash o dodanie metody as_json zamiast dodawania json_tree do trzech modeli.

Ponieważ ten wątek był bardzo pomocny, pomyślałem, że udostępnię tę modyfikację.

Ustawiono jako moduł lub małpa patch do 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 

Nazywamy model i wykorzystywać to zachowanie domyślne json. Nie wiem, czy powinienem zadzwonić pod numer do _json lub jako _json. Użyłem tutaj as_json i działa w moim kodzie.

W regulatorze

... 
format.json { render :json => @goal.arrange} 
... 
Powiązane problemy