Как создать дерево JSON из предков - PullRequest
9 голосов
/ 30 марта 2012

Я использую происхождение, чтобы сделать дерево целей. Я хотел бы отправить содержимое этого дерева в браузер, используя json.

Мой контроллер такой:

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

Когда я открываю файл json, я получаю следующий вывод:

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

Как отобразить содержимое объектов Goal в файле json?

Я пробовал это:

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

но это не работает, поскольку @goals - это упорядоченный хеш.

Ответы [ 3 ]

11 голосов
/ 31 марта 2012

Я получил некоторую помощь от пользователя tejo по адресу https://github.com/stefankroes/ancestry/issues/82.

. Решение состоит в том, чтобы поместить этот метод в целевую модель:

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

, а затем заставить контроллер выглядеть так:

@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 голосов
/ 18 апреля 2013

Вдохновленный этим 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 голосов
/ 31 января 2014

Я столкнулся с этой проблемой на днях (родословная 2.0.0).Я изменил ответ Йохана для моих нужд.У меня есть три модели, использующие родословную, поэтому имеет смысл расширить OrderedHash, добавив метод as_json вместо добавления json_tree к трем моделям.

Поскольку этот поток был очень полезным, я решил поделиться этой модификацией.1003 *

Установите это как патч модуля или обезьяны для 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

Мы вызываем модель и используем ее поведение json по умолчанию.Не уверен, стоит ли мне звонить с на _json или как _json.Я использовал as_json здесь, и он работает в моем коде.

В контроллере

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