0

I know a few questions with a similar title have been closed for ambiguity, so I will try to be as detailed as possible.

I have a rails model called 'Badges' that have 13 badge objects that are predefined. Each badge object has a attr called 'condition', which specifies the number of points that a user must reach to achieve the badge.

My code for a method called 'reward_badge' is like this:

@user = User.find(self.user_id)

conditions = Array.new(13)
Badge.all.each do |b|
  conditions << b.condition
end

badge = Badge.find(conditions.bsearch_index{|x| @user.points >= x} + 1)
@user.badges << badge unless @user.badges.include? badge

So, I have a sorted array called 'conditions' which contains the point increments for each of the badges (ex. [1, 5, 10, 50...]). I want to get the badge that has a condition which is just smaller than the user's points, and award the badge if the user doesn't already have it.

And I decided that the 'binary search' that ruby provides is the best way to achieve this. But when I use the above code, I get errors saying that 'x is nil'. (more specifically, the error says that I cannot use the operator '>=' for a nil obj)

I am not sure how to resolve this, as I thought I followed what the ruby library specifies...

At the moment, I decided to temporarily use a case statement. I really hope to use this binary search method for a clearer solution. I appreciate your help.

5
  • 2
    Why dont you use badge = Badge.where('condition <= ?', @user.points).order(:condition).last ? Commented Jul 26, 2017 at 9:02
  • @Sajin Oh... right. I've been so desperate to use search algorithms that I completely forgot that there is the quick&easy 'where' method in ruby... wow I really need my head to be more flexible. So sorry I wasted your time with this basic question! Would you like to put that as an answer or should I just close the question? :) Commented Jul 26, 2017 at 9:08
  • @sajin Thanks for the great tip by the way!! Commented Jul 26, 2017 at 9:09
  • I'll add it as an answer Commented Jul 26, 2017 at 9:09
  • @Sajin Thanks! :) Commented Jul 26, 2017 at 9:09

1 Answer 1

3

To fetch the badge based on user points, use:

badge = Badge.where('condition <= ?', @user.points).order(:condition).last
Sign up to request clarification or add additional context in comments.

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.