Tom Milner
Tom Milner

Reputation: 25

How do I iterate through Associations in Rails?

Ok, So I have a review model, and a votes model (Upvotes and Downvotes modeled through a single variable 'likes', If its true its an upvote, if its false its a downvote.). The votes are a has_many relation, and are polymorphic (I hope to be able to use this on more than just reviews later on).

So in the reviews model has the line

 has_many :votes, :as => :votable

And the votes model is defined like this

class Vote < ActiveRecord::Base
  belongs_to :votable, :polymorphic => true
  belongs_to :user

  def upvote?
    like
  end

  def downvote?
    !like
  end
end

Now this is fine, I can upvote, downvote and remove votes just fine. But I'm trying to generate a score bassed on the upvotes and downvotes (Simply upvotes-downvotes for now). To do this I added the following to the reviews model

def score
  up = 0
  down = 0
  self.votes.each do |v|
    if v.upvote?
      up += 1
    elsif v.downvote?
      down += 1
    end
  end
  up-down
end

However I always get 0 back as the answer. The error is in the loop, as I can set the up or down variables to be what ever outside of it and they are passed through. Its starting to drive me insane, and I have no idea where im going wrong.

Upvotes: 1

Views: 1095

Answers (2)

Benjamin
Benjamin

Reputation: 1862

If you are sure the error is in the loop then here's my best guess:

you have v.upvote? as an if, and v.downvote? as an elsif.

What happens if both of these are false? I am pretty sure nothing will happen. And therefore, 0 - 0 = 0 and you always get zero back. The loop is perfectly fine, if your v.upvote? and v.downvote? are written correctly, or they are the correct values to begin with.

Try:

if v.upvote?
 ...
else
 ...
end

Obviously you have those setup in that way for a reason, but you are possibly just zoning in on the wrong thing.

Hope this helps.

Upvotes: 0

MatthewFord
MatthewFord

Reputation: 2926

For starters it might be best to use the database to count the number of down and upvotes with a named scope.

Then once you have the total counts, you can subtract downvotes from upvotes.

For more info on scopes see: http://guides.rubyonrails.org/active_record_querying.html#scopes

Upvotes: 1

Related Questions