ruby-on-railsajaxacts-as-votable

Acts as votable - refresh likes-count on home page [Rails - AJAX]


i have a little problem with acts as votable.

My likes button and the count is refreshed correctly (with AJAX) on the page of each of my "softwares". But does not work properly on the home page (or there are several softwares).

When I click on a like button (on my homepage), the likes-count is updated but the value is updated and is identical for all software (but when I manually refresh the page the values are correct).

I can not find the solution for this problem.

My codes:

softwares_controller.rb

 def upvote
    if !current_user.liked? @software
      @software.liked_by current_user
    elsif current_user.liked? @software
      @software.unliked_by current_user 
    end
    respond_to do |format|
        format.html { redirect_back(fallback_location: root_path) }
        format.js 
        end
  end 

softwares/show

<%= link_to like_software_path(@software), class:"like-btn", method: :put, remote: true do %> 
    <button class="btn btn-warning"> 
      <span><p><i class="fa fa-thumbs-up fa-lg" aria-hidden="true"></i></p></span>
    </button> 
<% end %>
<span class="likes-count"> <%= @software.get_upvotes.size %> </span> 

homepage view

<%= link_to like_software_path(software), class:"like-btn", method: :put, remote: true do %> 
    <button class="btn btn-warning"> 
      <span><p><i class="fa fa-thumbs-up fa-lg" aria-hidden="true"></i></p></span>
    </button> 
<% end %>
<span class="likes-count"> <%= software.get_upvotes.size %> </span>  

routes.rb

resources :softwares do
  member do
    put "like" => "softwares#upvote"
    put "dislike" => "softwares#downvote"
  end
end

softwares/upvotes.js.erb

<% if current_user.liked? @software %>
   $(".likes-btn").addClass("liked");
<% else %>
   $(".likes-btn").removeClass("liked");
<% end %>
   $(".likes-count").addClass("liked").html('<%= @software.get_upvotes.size %>');

EDIT : Or when i change my homepage with :

<%= link_to like_software_path(@software), class:"like-btn", method: :put, remote: true do %> 
    <button class="btn btn-warning"> 
      <span><p><i class="fa fa-thumbs-up fa-lg" aria-hidden="true"></i></p></span>
    </button> 
<% end %>
<span class="likes-count"> <%= @software.get_upvotes.size %> </span> 

i have an error :

No route matches {:action=>"upvote", :controller=>"softwares", :id=>nil}, missing required keys: [:id]

Solution

  • This line:

    $(".likes-count").addClass("liked").html('<%= @software.get_upvotes.size %>');
    

    is updating the displayed vote count value of all the elements with the .likes-count class. To fix this, change:

    <span class="likes-count"> <%= software.get_upvotes.size %> </span>
    

    to include the id of the software, and target it within your js.

    <span class="likes-count" id="software-<%= software.id %>">
      <%= software.get_upvotes.size %>
    </span>
    

    softwares/upvotes.js.erb

    $("#software-<%= @software.id %>").addClass("liked").html('<%= @software.get_upvotes.size %>');