1

I'm having a problem trying to get a recursive method to work in rails/ruby. The purpose is to find all ancestor categories of a given category based on the parent_id. The current method does return the right ancestor categories, but it is nesting the array. I think this is because I'm initializing the category_ancestors array, and then it is getting reinitialized as the method recurses through itself. I'm trying to figure out how to change this so that I get a single level array with the category attributes rather than how it is outputting the data now.

def self.get_ancestors(category)

category_ancestors = []   # <-- this seems to be the problem

category_ancestors << category.attributes

if category.has_parent?
  category.get_parent.each do |parent_category|
    category_ancestors << get_ancestors(parent_category)
  end
end

category_ancestors.reverse

end

This returns something like which is nesting the arrays (but I need them all at the same level):

--- 
  - - - name: Category 1
    id: 1
    created_at: 2011-09-04 22:56:43.198413 Z
    updated_at: 2011-09-07 00:14:09.934813 Z
    parent:id 

 - name: Category 2
   id: 2
   created_at: 2011-09-04 22:56:43.198413 Z
   updated_at: 2011-09-07 00:14:09.934813 Z
   parent:id: 1

- name: Category 3
  id: 3
  created_at: 2011-09-04 22:56:43.198413 Z
  updated_at: 2011-09-07 00:14:09.934813 Z
  parent:id: 2

3 Answers 3

1

Here's a non-recursive version that does the same thing

class Category
  def ancestors
    result = []
    c = self
    while c.parent
      result.unshift(c.parent)
      c = c.parent
    end
    result
  end
end
Sign up to request clarification or add additional context in comments.

Comments

0

If you need a flat array, you should use concat() to join the elements into a single array instead of ending up with an array of arrays.

  def self.get_ancestors(category)

    category_ancestors = []   # <-- this seems to be the problem

    category_ancestors << category.attributes

    if category.has_parent?
      category.get_parent.each do |parent_category|
        category_ancestors.concat(get_ancestors(parent_category))
      end
    end

    category_ancestors.reverse

  end

1 Comment

Thanks very much, I now see that I should have been using concat to keep things in a single array.
0

I would use something like this:

category_ancestors += get_ancestors(parent_category)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.