k_Dank
k_Dank

Reputation: 695

Correctly implementing Recursive methods in Ruby on rails

repeat_purchases_percent is a method in my Category model. All parentless categories are guarenteed to have a value for future_purchases_percent in the database. Subcategories may or may not have a future_purchases_percent. if they do, i want to use that value. If not, I want to use the parent's value and so on.

I tried a recursive method.

def future_purchases_percent
  if self.future_purchases_percent.nil?
    Category.find(self.parent_id).future_purchases_percent
  else
    future_purchases_percent
  end
end

This gets stuck in a loop where it keeps evaluating:

if self.future_purchases_percent.nil?

how can i correctly implement this method?

Upvotes: 2

Views: 1968

Answers (2)

tokland
tokland

Reputation: 67860

  1. Your method gets stuck because it has the same name than the attribute (so it's calling itself), pick a different name.
  2. Notice that this conditional is nothing more than a simple a || b expression.
  3. You should add a belongs_to :parent, :foreign_key => 'parent_id', :class_name => :Category to this model.

Now, with everything in place, you can write real declarative code:

def safe_future_purchases_percent
  future_purchases_percent || parent.safe_future_purchases_percent
end

Upvotes: 5

Andrew Hubbs
Andrew Hubbs

Reputation: 9426

  def repeat_purchases_percent
    if self.future_purchases_percent.nil?
      Category.find(self.parent_id).repeat_purchases_percent
    else
      future_purchases_percent
    end
  end

Basically your problem is that you named your method the same thing as the field and then immediately call it. You should instead name the method like you said repeat_purchases_percent and only recurse into it when the future_purchases_percent is nil.

Upvotes: 0

Related Questions