I'm new to Ruby On Rails, I used the acts_as_votable gem to create Like and Unlike Buttons to make Users like and unlike Posts but I can't make them change from Like to Unlike (and viceversa) and update the counter each time they click without refreshing the page. I tried following other kind-of-similar answers but I had no luck. Without the messy changes I tried to do to implement Ajax my code looked like this:
Post Model acts_as_votable and User Model acts_as voter
Posts Controller has
def like
@post = Post.find(params[:id])
@post.liked_by current_user
redirect_to :back
end
def unlike
@post = Post.find(params[:id])
@post.unliked_by current_user
redirect_to :back
end
Routes have
resources :posts do
member do
put 'like', to: "posts#like"
put 'unlike', to: "posts#unlike"
end
end
View has
<%= @post.get_likes.size%>
<% if @post.get_likes.size ==1 %>
person like this
<% else %>
people like this
<% end %>
<div class="btn-group">
<% if (current_user.liked? @post) %>
<%= link_to unlike_post_path(@post), method: :put, class: "btn btn-default btn-sm" do %>
<span class="glyphicon glyphicon-chevron-down"></span>
Unlike
<%end %>
<% else %>
<%= link_to like_post_path(@post), method: :put, class: "btn btn-primary btn-sm" do %>
<span class="glyphicon glyphicon-chevron-up"></span>
Like
<% end %>
<% end %>
</div>
I read a lot of answers about Ajax but I was unable to replicate the results. Thank you in advance!
First, you need to point out your posts controller to respond to js format. Then the two actions in
posts_controller
become:Second, you need to pass
remote: true
on your links:I change
method: :put
tomethod: :get
, so change it in yourconfig/routes.rb
, and add a class to your links to bind it in js.Finally, you need to create 2 views in
app/views/posts/
:like.js.erb
unlike.js.erb
To handle update of count, I use a
.vote_count
class, so in your view:So my view:
Edit: I edit my answer. Update your links with class instead id. And take a look at 2 js view to find closest(). It works well in index and show page in my sandbox app. So feel free to adapt to your markup.