2008-09-03 6 views
1

재귀를 사용하지 않고 Ruby on Rails의 acts_as_nested_set에있는 모든 노드에서 JSON 해시를 신속하고 신속하게 반환 할 수있는 방법이 있습니까?Ruby는 acts_as_nested_set을 재귀없이 JSON 해시로 변환 할 수 있습니까?

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

사용중인 재귀 솔루션에 대한 다른 대안을 보여줍니다 트리 탐색에 wikipedia article 있습니다 :

여기 참조 용 재귀 솔루션입니다. 특정 경우에 사용하는 것은 까다로운 일일 수 있지만 가능해야합니다.

그러나 내 질문에 재귀 대신 반복을 사용하려는 특별한 이유가 있습니까? 반복적 인 솔루션이 거의 깨끗하다고는 생각하지 않습니다. 당신의 나무는 너무 커서 커다란 스택 공간이 부족합니다. 그렇지 않으면 반복 솔루션이 실제로 더 빠를 것이라고 확신하지 못합니다. 성능 문제를보고하는 경우

나는, 그래도 개선 한 잠재력을 ...하지만 난 레일을 모르는, 그래서 정확한 있는지 확실하지 않습니다 :

가 찾기 방법은을 반환합니까

새로운 배열? 그렇다면. 콜렉트를 호출하고 싶을 것입니다. .collect 대신 find를 사용하면 배열을 만들면 배열을 만든 다음 수집 (배열도 생성) 호출에 던져 버리기 때문에 매우 효율적이지 않고 느려질 수 있습니다 큰 나무가 있다면 많이.

그래서

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

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

편집 될 수 있습니다 또한,이 해시의 당신의 해시를 생성하는 것이 더 효율적일 수 있습니다, 다음 급습 하락 1에서 JSON으로 전체를 변환, 당신이하는 것처럼 그것을 조각 메일로 변환하는 것보다.

그래서

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 

이 작동하고 난 당신이

+0

좋은 답변이지만이 작업을 수행하는 데있어 반복적 인 또는 멋진 루비 방법을 찾고있었습니다. – hoyhoy

1

JSONifier을 ;-)위한 운동으로 떠나 더 효율적인지 여부

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 

될 수도 있습니다!

node.to_json(:include=>{:products=>{:include=>:product_parts}})