1

I am creating a Rails 4 app in which a user can upvote a given post through the acts_as_votable gem. Let's say as a user I press the upvote button, how would I make it so that if I press the SAME button again, the vote gets taken away, so in essence an "unupvote"?

Here is what my upvote method looks like in my posts controller:

def upvote
  @post = Post.find(params[:id])
  @post.upvote_by current_user
  redirect_to :back
end

My post model

class Post < ActiveRecord::Base
  acts_as_votable
  belongs_to :user
end

And finally this how I am rendering the button in my views

<div class="btn-group">
  <%= link_to like_post_path(post), method: :put, class: "btn btn-default btn-sm" do %>
    <span class="glyphicon glyphicon-chevron-up"></span>
    Upvote
    <%= post.get_upvotes.size %>
  <% end %>
</div>

Thanks for the help guys!

1 Answers1

1

acts_as_votable has an unvote_up method you can use. I'd do something like this (assuming your like_post_path references the upvote action):

def upvote
  @post = Post.find(params[:id])

  if current_user.up_votes @post 
    @post.unvote_up current_user
  else
    @post.upvote_by current_user
  end

  @post.create_activity :upvote, owner: current_user
  redirect_to :back
end

You'll also need to add acts_as_voter to your User model so you can get the up_votes helper:

class User < ActiveRecord::Base
  acts_as_voter
end
Undo
  • 25,519
  • 37
  • 106
  • 129
  • I've never actually used the library before, let me know if this works or doesn't work and we can work through it. – Undo Jan 28 '16 at 18:46
  • 1
    I tried this and it didn't seem to work. I am able to unvote, however if I try to upvote it again, it does not work. – Eddie Campain Jan 28 '16 at 19:15
  • @EddieCampain That's interesting - can you try printing the value of `current_user.up_votes @post` in that method and letting me know what it says? If I'm reading https://github.com/ryanto/acts_as_votable/blob/9ded371ec0720d07fa7a169109da05c835a2cb51/lib/acts_as_votable/votable.rb#L120 right, it should be completely destroying the previous votes. – Undo Jan 28 '16 at 19:19
  • Thanks. The value that was printed was blargtrue – Eddie Campain Jan 28 '16 at 20:04
  • @EddieCampain Was that printed when you were trying to upvote after unupvoting? – Undo Jan 28 '16 at 20:10
  • Yes. Your method seems good to me, but I think it may be because in my views I have not associated an unvote action with the actual button. I have simply associated it with the upvote action thru the like_link_path. If this is the case, how would I go about achieving this in my views? – Eddie Campain Jan 29 '16 at 01:52
  • @EddieCampain You shouldn't need to make a new route if you changed the upvote action as described - it should unupvote instead of upvoting. I'm not really sure what's going wrong there. – Undo Jan 29 '16 at 01:53