Reputation: 65
I'm setting up my vote system, and trying to have a helper model so I can check if a user has voted for a card. I'm new to rails and can't seem to figure this one out.
How do I have the model check votes for a record that has the user_id
of the current_user
and the card_id
?
I'm also trying to limit calling the helper many times for each iteration of _cards.html.erb
by setting the voted
variable. Not sure how to do this, trying to set the variable is just printing true for every card, even the ones that have no votes.
Setting the variable is not working and neither is the helper, as it is always true.
cards_controller.rb:
def if_voted(card_id)
if Vote.where(:user_id => current_user.id, :card_id => card_id) then
true
else
false
end
end
helper_method :if_voted
_cards.html.erb:
<td>
<%= @voted = if_voted(card.id) %>
<% if @voted == true %>
<span class="green"><center>
<% elsif @voted == false %>
<span class="red"><center>
<% else %>
<span class="gray"><center>
<% end %>
<%= card.up_votes - card.down_votes %>
</center></span>
</td>
With the help of @tadman
cards_controller.rb
def if_voted(card_id)
if Vote.where(:user_id => current_user.id, :card_id => card_id).any? then
@vote = Vote.find_by(:user_id => current_user.id, :card_id => card_id)
return @vote.voted
else
return nil
end
end
helper_method :if_voted
_cards.html.erb
<td>
<% @voted = if_voted(card.id) %>
<% if @voted == true %>
<span class="green"><center>
<% elsif @voted == false %>
<span class="red"><center>
<% else %>
<span class="gray"><center>
<% end %>
<%= card.up_votes - card.down_votes %>
</center></span>
</td>
Thank you
Upvotes: 1
Views: 231
Reputation: 211540
The where
method always returns a scope even if that scope does not contain any records. The find_by
method uses the same options but returns either the first matching record or nil
if none are found.
That's not quite what you want here, though. You don't actually want to retrieve any of the records, but instead just check if they exist. The any?
method on a scope is true
if one or more records exist, or false
otherwise.
You should update your code to look like this:
def if_voted(card_id)
Vote.where(:user_id => current_user.id, :card_id => card_id).any?
end
It's worth noting a few things about your Ruby style:
then
at the end of an if
clause, while supported, is extraneous and generally not done.== true
is usually a sign your logic is confused. If you're concerned about something being literal true
rather than just logically true, use === true
instead. In this case, close enough counts, so if (if_voted(...))
should suffice.true
or false
but you had three conditions as if you were expecting a maybe
to pop up one day.if_voted
are a little clumsy, especially if used inside an if
. Something like has_voted?
is much more in line with Ruby and Rails in general, so you get if (has_voted?(...))
which reads a lot better.User
class so you can eliminate the helper and end up with if (current_user.has_voted?(card_id))
as a very clear way of expressing your intent.Upvotes: 4