Может ли Ruby конвертировать act_as_nested_set в JSON-хэш чисто без рекурсии? - PullRequest
1 голос
/ 03 сентября 2008

Существует ли быстрый и чистый способ возврата хеша JSON с любого узла в activ_as_nested_set Ruby on Rails без использования рекурсии?

Вот рекурсивное решение для справки:

class Node < ActiveRecord::Base
  has_many :products
  def json_hash
    if children.size > 0
      children.collect { |node| { node.name => node.json_hash }.to_json
    else
      { node.name => node.products.find(:all).collect(&:name) }.to_json
    end
  end
end

Ответы [ 2 ]

2 голосов
/ 03 сентября 2008

В статье википедии о обходе дерева показаны различные альтернативы рекурсивному решению, которое вы используете. Может быть сложно использовать их в вашем конкретном случае, но это должно быть возможно.

Однако мой вопрос к вам: есть ли конкретная причина, по которой вы хотите использовать итерацию вместо рекурсии? Я не думаю, что любое из итеративных решений будет почти таким же чистым. Ваши деревья настолько велики, что вам не хватает места в стеке (они должны быть довольно большими)? В противном случае, я не уверен, что итеративное решение действительно будет быстрее.

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

Возвращает ли метод find новый массив? Если это так, вы, вероятно, хотите вызвать .collect! вместо .collect, потому что, если find создает массив, вы просто создаете массив, а затем выбрасываете его в вызов метода collect (который также создает массив), что, безусловно, не будет очень эффективным и может замедлить работу много, если у вас там большое дерево.

Итак

{ node.name => node.products.find(:all).collect(&:name) }.to_json

может стать

{ node.name => node.products.find(:all).collect!(&:name) }.to_json

РЕДАКТИРОВАТЬ: Кроме того, может быть более эффективно создать ваш хэш хэшей, а затем конвертировать все это в json одним махом, а не конвертировать его по частям, как вы делаете.

So

class Node < ActiveRecord::Base
  has_many :products
  def json_hash
    if children.size > 0
      children.collect { |node| { node.name => node.json_hash }.to_json
    else
      { node.name => node.products.find(:all).collect!(&:name) }.to_json
    end
  end
end

может стать

class Node < ActiveRecord::Base
  has_many :products
  def json_hash
    to_hash.to_json
  end

  def to_hash
    if children.size > 0
      children.collect { |node| { node.name => node.to_hash }
    else
      { node.name => node.products.find(:all).collect!(&:name) }
    end
  end
end

Работает ли это и является ли это более эффективным, я оставляю вам упражнение; -)

1 голос
/ 28 августа 2010

JSONifier!

node.to_json(:include=>{:products=>{:include=>:product_parts}})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...