Marcin Doliwa
Marcin Doliwa

Reputation: 3659

Simple recursive method

I have Board model. Board can be subscribed to other boards (as a feed). Lets say I have board tree like this:

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

So: Board.find(2).feeds are boards 5 and 7 Board.find(7).feeds are boards 2 and 6 etc.

I want to write method all_feeds which returns all feeds from all levels for certain board. For example: Board.find(7).all_feeds would output array of boards with ids: 2,6,5,11

I started with something like:

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

Probably have to add this return feeds to some global array, but not sure how should I do this.

Thanks for help.

ps. this is not always a binary tree, you can have more than 2 feeds.

Upvotes: 2

Views: 143

Answers (3)

Ju Liu
Ju Liu

Reputation: 3999

I guess that what you want could be achieved with:

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

Array#flatten makes the result one-dimensional, while Array#compact removes the nil components.

For an explanation of the map(&:all_feeds) part, you can refer to this SO answer :)

Upvotes: 1

okliv
okliv

Reputation: 3959

if it is allowed to use gems ancestry gem will help do the trick

Board.find(7).descendants

in this case it will be definitely one request to db without any recursion which is better for performance

you can implement ancestry idea without gem (or in top of it):

  • add ancestry field to your model

  • fill it correctly when you build your tree (for nested nodes with ids 2 and 6 it will be 2/7, with ids 5 and 11 - 2/7/6 )

  • and then just take it from db with like 2/% query

Upvotes: 0

Marcin Doliwa
Marcin Doliwa

Reputation: 3659

Looks like it's working for below code:

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

Upvotes: 1

Related Questions