2013-06-28 93 views
2

我有董事会模型。董事会可以订阅其他董事会(作为饲料)。 可以说我有板树是这样的:简单的递归方法

http://upload.wikimedia.org/wikipedia/commons/thumb/f/f7/Binary_tree.svg/200px-Binary_tree.svg.png

所以说: Board.find(2).feeds是板5和7 Board.find(7).feeds是板2和6等

我想写方法all_feeds返回所有来自各个层面的特定董事会的饲料。例如: Board.find(7).all_feeds将板的输出数组与IDS:2,6,5,11

我开始喜欢的东西:

def all_feeds 
    if feeds.empty? 
     return 
    else 
     feeds.each {|feed| feed.all_feeds} 
     return feeds 
    end 
    end 

可能要添加此回提供给一些全局数组,但不知道我该怎么做。

感谢您的帮助。

PS。这并不总是一个二叉树,你可以有两个以上的提要。

回答

1

我猜你想要的东西可以用以下方式实现:

def all_feeds 
    unless feeds.empty? 
    feeds + feeds.map(&:all_feeds).flatten.compact 
    end 
end 

Array#flatten,使得结果一维的,而Array#compact删除零组件。

对于map(&:all_feeds)部分的说明,可以参考this SO answer :)

+0

它不起作用,我添加了新代码,我认为它正在工作,必须测试它。 –

+0

哎呀,我想我忘了包括之前的当前水平饲料。查看更新的答案! –

1

看起来像它的工作了下面的代码:如果允许使用的宝石ancestry创业板将帮助做

def all_feeds 
    if feeds.empty? 
     self 
    else 
     [self]+feeds.map(&:all_feeds) 
    end 
    end 
+0

我想你在这里有递归节点id = 2,它会返回自己的树,每次你在本身映射'all_feeds'一次又一次 – okliv

+0

'all_feeds'应该总是返回相同的类型。 '[self] + feeds.map(&:all_feeds)'是你所需要的。 – tokland

0

技巧

Board.find(7).descendants 

在这种情况下,它肯定会有一个请求db没有任何递归,这是bett呃性能

可以实现祖先的想法没有宝石(或在它的上面):

  • ancestry字段添加到您的模型

  • 正确填写它,当你建立你的树(用于具有ID的2和6嵌套节点将是2/7,使用IDS 5和11 - 2/7/6

  • ,然后只把它从分贝与like 2/%查询