Kurta
Kurta

Reputation: 41

How to "Add to favorites" with ajax in rails 5?

After a long search I've come here for help! How can I make favorite button with ajax in rails to work?

Code below works, but when I refresh the page, the button is back to unliked(icon with empty heart).

So far I've used act_as_votable gem to create this below, but now I'm stuck.

Here is my code:

songs_controller.rb

before_action :find_song, {only: [:edit, :update, :show, :destroy, :like, :unlike]}

def like
    @song = Song.find(params[:id])
    @song.liked_by current_user
    respond_to do |format|
        format.html { redirect_to :back }
        format.js { render layout: false }
    end
end

def unlike
    @song = Song.find(params[:id])
    @song.unliked_by current_user
    respond_to do |format|
        format.html { redirect_to :back }
        format.js { render layout: false }
    end

partial _song.html.erb

    <div class="votes">
    <% unless current_user.liked? song %>
       <%= link_to unlike_song_path(song), method: :get, remote: true, class: 'unlike_song' do %> 
       <i class="fa fa-heart-o"></i>
     <% end %>
       <% else %>
       <%= link_to like_song_path(song), method: :get, remote: true, class: 'like_song' do %>
       <i class="fa fa-heart"></i>
    <% end %>  
   <% end %> 
  </div>
  </td>

like.js.erb

    $('.like_song').bind('ajax:success', function(){
   $(this).parent().parent().find('.vote_count').html('<%= escape_javascript @song.votes_for.size.to_s %>');
   $(this).closest('.like_song').hide();
   $(this).closest('.votes').html(' <%= link_to '<i class="fa fa-heart-o"></i>'.html_safe, unlike_song_path(@song), remote: true, method: :get, class: 'unlike_song' %>');
});

unlike.js.erb

$('.unlike_song').bind('ajax:success', function(){
   $(this).parent().parent().find('.vote_count').html('<%= escape_javascript @song.votes_for.size.to_s %>');
   $(this).closest('.unlike_song').hide();
   $(this).closest('.votes').html('<%= link_to '<i class="fa fa-heart"></i>'.html_safe, like_song_path(@song), remote: true, method: :get, class: 'like_song' %>');

});

routes.rb

 resources :songs do
    member do
      get 'like', to: "songs#like"
      get 'unlike', to: "songs#unlike"
    end
  end

Note: I'm a rookie at this. Thanks!

Upvotes: 1

Views: 474

Answers (1)

Sebasti&#225;n Palma
Sebasti&#225;n Palma

Reputation: 33470

Instead checking with unless if the user has liked the song, use an if conditional:

<% if current_user.liked? song %>
  <%= link_to unlike_song_path(song), method: :get, remote: true, class: 'unlike_song' do %> 
    <i class="fa fa-heart-o"></i>
  <% end %>
<% else %>
  <%= link_to like_song_path(song), method: :get, remote: true, class: 'like_song' do %>
    <i class="fa fa-heart"></i>
  <% end %>  
<% end %> 

Upvotes: 1

Related Questions