Rails/JS - Like button with AJAX in 2018












0














I've got the following project: (not using acts_as_votable gem, apart from all the other threads I found here!)



There is a Beat model which has_many :likes and belongs_to :user, a beat has_many :likes and belongs_to :beat. In my LikesController I got a create and a destroy action to create a new like whenever a Beat is liked.
The liking functionality works quite well, however, the page reloads with each like/unlike. Using AJAX I want to show the current like status (solid heart = liked) without having to reload the page or redirect_to somewhere.



controllers/likes_controller.rb:



class LikesController < ApplicationController

def create
@beat = Beat.find(params[:beat_id])

if already_liked?
flash[:notice] = "You can't like more than once!"
else
@beat.likes.create(user_id: current_user.id)
end
end

def destroy
@beat = Beat.find(params[:beat_id])
@like = @beat.likes.find(params[:id])
if !already_liked?
flash[:notice] = "Can't unlike!"
else
@like.destroy
end
end

private
def already_liked?
Like.where(user_id: current_user.id, beat_id: params[:beat_id]).exists?
end
end


views/beats/show.html.haml



= @beat.likes.count
= (@beat.likes.count) == 1 ? 'Like' : 'Likes'

- previous_like = @beat.likes.find { |like| like.user_id == current_user.id}
- if previous_like
= button_to 'Unlike', beat_like_path(@beat, previous_like), method: :delete, remote: true
- else
= button_to 'Like', beat_likes_path(@beat), method: :post, remote: true

= link_to 'Back', :beats


By using remote: true I can send an AJAX request to my controller, but first how do I handle this in my controller? How do I send back a JSON/XML ajax-like response and last: how do I handle this response from my controller with JS to display in my show.html.haml?










share|improve this question



























    0














    I've got the following project: (not using acts_as_votable gem, apart from all the other threads I found here!)



    There is a Beat model which has_many :likes and belongs_to :user, a beat has_many :likes and belongs_to :beat. In my LikesController I got a create and a destroy action to create a new like whenever a Beat is liked.
    The liking functionality works quite well, however, the page reloads with each like/unlike. Using AJAX I want to show the current like status (solid heart = liked) without having to reload the page or redirect_to somewhere.



    controllers/likes_controller.rb:



    class LikesController < ApplicationController

    def create
    @beat = Beat.find(params[:beat_id])

    if already_liked?
    flash[:notice] = "You can't like more than once!"
    else
    @beat.likes.create(user_id: current_user.id)
    end
    end

    def destroy
    @beat = Beat.find(params[:beat_id])
    @like = @beat.likes.find(params[:id])
    if !already_liked?
    flash[:notice] = "Can't unlike!"
    else
    @like.destroy
    end
    end

    private
    def already_liked?
    Like.where(user_id: current_user.id, beat_id: params[:beat_id]).exists?
    end
    end


    views/beats/show.html.haml



    = @beat.likes.count
    = (@beat.likes.count) == 1 ? 'Like' : 'Likes'

    - previous_like = @beat.likes.find { |like| like.user_id == current_user.id}
    - if previous_like
    = button_to 'Unlike', beat_like_path(@beat, previous_like), method: :delete, remote: true
    - else
    = button_to 'Like', beat_likes_path(@beat), method: :post, remote: true

    = link_to 'Back', :beats


    By using remote: true I can send an AJAX request to my controller, but first how do I handle this in my controller? How do I send back a JSON/XML ajax-like response and last: how do I handle this response from my controller with JS to display in my show.html.haml?










    share|improve this question

























      0












      0








      0







      I've got the following project: (not using acts_as_votable gem, apart from all the other threads I found here!)



      There is a Beat model which has_many :likes and belongs_to :user, a beat has_many :likes and belongs_to :beat. In my LikesController I got a create and a destroy action to create a new like whenever a Beat is liked.
      The liking functionality works quite well, however, the page reloads with each like/unlike. Using AJAX I want to show the current like status (solid heart = liked) without having to reload the page or redirect_to somewhere.



      controllers/likes_controller.rb:



      class LikesController < ApplicationController

      def create
      @beat = Beat.find(params[:beat_id])

      if already_liked?
      flash[:notice] = "You can't like more than once!"
      else
      @beat.likes.create(user_id: current_user.id)
      end
      end

      def destroy
      @beat = Beat.find(params[:beat_id])
      @like = @beat.likes.find(params[:id])
      if !already_liked?
      flash[:notice] = "Can't unlike!"
      else
      @like.destroy
      end
      end

      private
      def already_liked?
      Like.where(user_id: current_user.id, beat_id: params[:beat_id]).exists?
      end
      end


      views/beats/show.html.haml



      = @beat.likes.count
      = (@beat.likes.count) == 1 ? 'Like' : 'Likes'

      - previous_like = @beat.likes.find { |like| like.user_id == current_user.id}
      - if previous_like
      = button_to 'Unlike', beat_like_path(@beat, previous_like), method: :delete, remote: true
      - else
      = button_to 'Like', beat_likes_path(@beat), method: :post, remote: true

      = link_to 'Back', :beats


      By using remote: true I can send an AJAX request to my controller, but first how do I handle this in my controller? How do I send back a JSON/XML ajax-like response and last: how do I handle this response from my controller with JS to display in my show.html.haml?










      share|improve this question













      I've got the following project: (not using acts_as_votable gem, apart from all the other threads I found here!)



      There is a Beat model which has_many :likes and belongs_to :user, a beat has_many :likes and belongs_to :beat. In my LikesController I got a create and a destroy action to create a new like whenever a Beat is liked.
      The liking functionality works quite well, however, the page reloads with each like/unlike. Using AJAX I want to show the current like status (solid heart = liked) without having to reload the page or redirect_to somewhere.



      controllers/likes_controller.rb:



      class LikesController < ApplicationController

      def create
      @beat = Beat.find(params[:beat_id])

      if already_liked?
      flash[:notice] = "You can't like more than once!"
      else
      @beat.likes.create(user_id: current_user.id)
      end
      end

      def destroy
      @beat = Beat.find(params[:beat_id])
      @like = @beat.likes.find(params[:id])
      if !already_liked?
      flash[:notice] = "Can't unlike!"
      else
      @like.destroy
      end
      end

      private
      def already_liked?
      Like.where(user_id: current_user.id, beat_id: params[:beat_id]).exists?
      end
      end


      views/beats/show.html.haml



      = @beat.likes.count
      = (@beat.likes.count) == 1 ? 'Like' : 'Likes'

      - previous_like = @beat.likes.find { |like| like.user_id == current_user.id}
      - if previous_like
      = button_to 'Unlike', beat_like_path(@beat, previous_like), method: :delete, remote: true
      - else
      = button_to 'Like', beat_likes_path(@beat), method: :post, remote: true

      = link_to 'Back', :beats


      By using remote: true I can send an AJAX request to my controller, but first how do I handle this in my controller? How do I send back a JSON/XML ajax-like response and last: how do I handle this response from my controller with JS to display in my show.html.haml?







      javascript ruby-on-rails ajax






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 22 at 21:26









      F. Amg

      104




      104
























          1 Answer
          1






          active

          oldest

          votes


















          0















          controllers/likes_controller.rb




            def create
          @beat = Beat.find(params[:beat_id])

          if already_liked?
          flash.now[:notice] = "You can't like more than once!"
          else
          @beat.likes.create(user_id: current_user.id)
          end
          end



          views/beats/show.html.erb




          <p id="likes-count"><%= pluralize(@beat.likes.count, 'Like') %></p>
          <div id="like-button"><%= like_button_tag @beat, previous_like %></div>



          helpers/beats_helper.rb




          module ApplicationHelper
          def like_button_tag beat, previous_like
          return button_to 'Unlike', beat_like_path(beat, previous_like), method: :delete, remote: true if previous_like
          button_to 'Like', beat_likes_path(beat), method: :post, remote: true
          end
          end



          views/beats/create.js.erb




          $('#likes-count').html('<%= pluralize(@beat.likes.count, 'Like') %>');
          $('#like-button').html('<%= like_button_tag @beat, previous_like %>');


          you can also use haml instead of erb






          share|improve this answer





















          • let me know if there is any problem
            – Sikandar Tariq
            Nov 23 at 6:22










          • Wow you are awesome, thank you a lot!
            – F. Amg
            Nov 23 at 9:30










          • happy to help @F.Amg
            – Sikandar Tariq
            Nov 23 at 9:31










          • Hey one question Sikandar: I just found out the create.js.erb isn't being loaded/used somehow, when I delete the content its still working, what was the create.js.erb even used for? I wanted to get rid of the scrolling to top when I like/unlike a Beat. I tried to use e.preventDefault on the #like-button within the create.js.erb but nothing in there is being loaded/executed?
            – F. Amg
            Dec 4 at 15:14










          • @F.Amg create.js.erb is the view that renders for remote: true requests... if create.js.erb is not working it means that requests may not be rendering as js format and page whole page is being refreshed
            – Sikandar Tariq
            Dec 5 at 6:47











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53438145%2frails-js-like-button-with-ajax-in-2018%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          0















          controllers/likes_controller.rb




            def create
          @beat = Beat.find(params[:beat_id])

          if already_liked?
          flash.now[:notice] = "You can't like more than once!"
          else
          @beat.likes.create(user_id: current_user.id)
          end
          end



          views/beats/show.html.erb




          <p id="likes-count"><%= pluralize(@beat.likes.count, 'Like') %></p>
          <div id="like-button"><%= like_button_tag @beat, previous_like %></div>



          helpers/beats_helper.rb




          module ApplicationHelper
          def like_button_tag beat, previous_like
          return button_to 'Unlike', beat_like_path(beat, previous_like), method: :delete, remote: true if previous_like
          button_to 'Like', beat_likes_path(beat), method: :post, remote: true
          end
          end



          views/beats/create.js.erb




          $('#likes-count').html('<%= pluralize(@beat.likes.count, 'Like') %>');
          $('#like-button').html('<%= like_button_tag @beat, previous_like %>');


          you can also use haml instead of erb






          share|improve this answer





















          • let me know if there is any problem
            – Sikandar Tariq
            Nov 23 at 6:22










          • Wow you are awesome, thank you a lot!
            – F. Amg
            Nov 23 at 9:30










          • happy to help @F.Amg
            – Sikandar Tariq
            Nov 23 at 9:31










          • Hey one question Sikandar: I just found out the create.js.erb isn't being loaded/used somehow, when I delete the content its still working, what was the create.js.erb even used for? I wanted to get rid of the scrolling to top when I like/unlike a Beat. I tried to use e.preventDefault on the #like-button within the create.js.erb but nothing in there is being loaded/executed?
            – F. Amg
            Dec 4 at 15:14










          • @F.Amg create.js.erb is the view that renders for remote: true requests... if create.js.erb is not working it means that requests may not be rendering as js format and page whole page is being refreshed
            – Sikandar Tariq
            Dec 5 at 6:47
















          0















          controllers/likes_controller.rb




            def create
          @beat = Beat.find(params[:beat_id])

          if already_liked?
          flash.now[:notice] = "You can't like more than once!"
          else
          @beat.likes.create(user_id: current_user.id)
          end
          end



          views/beats/show.html.erb




          <p id="likes-count"><%= pluralize(@beat.likes.count, 'Like') %></p>
          <div id="like-button"><%= like_button_tag @beat, previous_like %></div>



          helpers/beats_helper.rb




          module ApplicationHelper
          def like_button_tag beat, previous_like
          return button_to 'Unlike', beat_like_path(beat, previous_like), method: :delete, remote: true if previous_like
          button_to 'Like', beat_likes_path(beat), method: :post, remote: true
          end
          end



          views/beats/create.js.erb




          $('#likes-count').html('<%= pluralize(@beat.likes.count, 'Like') %>');
          $('#like-button').html('<%= like_button_tag @beat, previous_like %>');


          you can also use haml instead of erb






          share|improve this answer





















          • let me know if there is any problem
            – Sikandar Tariq
            Nov 23 at 6:22










          • Wow you are awesome, thank you a lot!
            – F. Amg
            Nov 23 at 9:30










          • happy to help @F.Amg
            – Sikandar Tariq
            Nov 23 at 9:31










          • Hey one question Sikandar: I just found out the create.js.erb isn't being loaded/used somehow, when I delete the content its still working, what was the create.js.erb even used for? I wanted to get rid of the scrolling to top when I like/unlike a Beat. I tried to use e.preventDefault on the #like-button within the create.js.erb but nothing in there is being loaded/executed?
            – F. Amg
            Dec 4 at 15:14










          • @F.Amg create.js.erb is the view that renders for remote: true requests... if create.js.erb is not working it means that requests may not be rendering as js format and page whole page is being refreshed
            – Sikandar Tariq
            Dec 5 at 6:47














          0












          0








          0







          controllers/likes_controller.rb




            def create
          @beat = Beat.find(params[:beat_id])

          if already_liked?
          flash.now[:notice] = "You can't like more than once!"
          else
          @beat.likes.create(user_id: current_user.id)
          end
          end



          views/beats/show.html.erb




          <p id="likes-count"><%= pluralize(@beat.likes.count, 'Like') %></p>
          <div id="like-button"><%= like_button_tag @beat, previous_like %></div>



          helpers/beats_helper.rb




          module ApplicationHelper
          def like_button_tag beat, previous_like
          return button_to 'Unlike', beat_like_path(beat, previous_like), method: :delete, remote: true if previous_like
          button_to 'Like', beat_likes_path(beat), method: :post, remote: true
          end
          end



          views/beats/create.js.erb




          $('#likes-count').html('<%= pluralize(@beat.likes.count, 'Like') %>');
          $('#like-button').html('<%= like_button_tag @beat, previous_like %>');


          you can also use haml instead of erb






          share|improve this answer













          controllers/likes_controller.rb




            def create
          @beat = Beat.find(params[:beat_id])

          if already_liked?
          flash.now[:notice] = "You can't like more than once!"
          else
          @beat.likes.create(user_id: current_user.id)
          end
          end



          views/beats/show.html.erb




          <p id="likes-count"><%= pluralize(@beat.likes.count, 'Like') %></p>
          <div id="like-button"><%= like_button_tag @beat, previous_like %></div>



          helpers/beats_helper.rb




          module ApplicationHelper
          def like_button_tag beat, previous_like
          return button_to 'Unlike', beat_like_path(beat, previous_like), method: :delete, remote: true if previous_like
          button_to 'Like', beat_likes_path(beat), method: :post, remote: true
          end
          end



          views/beats/create.js.erb




          $('#likes-count').html('<%= pluralize(@beat.likes.count, 'Like') %>');
          $('#like-button').html('<%= like_button_tag @beat, previous_like %>');


          you can also use haml instead of erb







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 23 at 4:41









          Sikandar Tariq

          415414




          415414












          • let me know if there is any problem
            – Sikandar Tariq
            Nov 23 at 6:22










          • Wow you are awesome, thank you a lot!
            – F. Amg
            Nov 23 at 9:30










          • happy to help @F.Amg
            – Sikandar Tariq
            Nov 23 at 9:31










          • Hey one question Sikandar: I just found out the create.js.erb isn't being loaded/used somehow, when I delete the content its still working, what was the create.js.erb even used for? I wanted to get rid of the scrolling to top when I like/unlike a Beat. I tried to use e.preventDefault on the #like-button within the create.js.erb but nothing in there is being loaded/executed?
            – F. Amg
            Dec 4 at 15:14










          • @F.Amg create.js.erb is the view that renders for remote: true requests... if create.js.erb is not working it means that requests may not be rendering as js format and page whole page is being refreshed
            – Sikandar Tariq
            Dec 5 at 6:47


















          • let me know if there is any problem
            – Sikandar Tariq
            Nov 23 at 6:22










          • Wow you are awesome, thank you a lot!
            – F. Amg
            Nov 23 at 9:30










          • happy to help @F.Amg
            – Sikandar Tariq
            Nov 23 at 9:31










          • Hey one question Sikandar: I just found out the create.js.erb isn't being loaded/used somehow, when I delete the content its still working, what was the create.js.erb even used for? I wanted to get rid of the scrolling to top when I like/unlike a Beat. I tried to use e.preventDefault on the #like-button within the create.js.erb but nothing in there is being loaded/executed?
            – F. Amg
            Dec 4 at 15:14










          • @F.Amg create.js.erb is the view that renders for remote: true requests... if create.js.erb is not working it means that requests may not be rendering as js format and page whole page is being refreshed
            – Sikandar Tariq
            Dec 5 at 6:47
















          let me know if there is any problem
          – Sikandar Tariq
          Nov 23 at 6:22




          let me know if there is any problem
          – Sikandar Tariq
          Nov 23 at 6:22












          Wow you are awesome, thank you a lot!
          – F. Amg
          Nov 23 at 9:30




          Wow you are awesome, thank you a lot!
          – F. Amg
          Nov 23 at 9:30












          happy to help @F.Amg
          – Sikandar Tariq
          Nov 23 at 9:31




          happy to help @F.Amg
          – Sikandar Tariq
          Nov 23 at 9:31












          Hey one question Sikandar: I just found out the create.js.erb isn't being loaded/used somehow, when I delete the content its still working, what was the create.js.erb even used for? I wanted to get rid of the scrolling to top when I like/unlike a Beat. I tried to use e.preventDefault on the #like-button within the create.js.erb but nothing in there is being loaded/executed?
          – F. Amg
          Dec 4 at 15:14




          Hey one question Sikandar: I just found out the create.js.erb isn't being loaded/used somehow, when I delete the content its still working, what was the create.js.erb even used for? I wanted to get rid of the scrolling to top when I like/unlike a Beat. I tried to use e.preventDefault on the #like-button within the create.js.erb but nothing in there is being loaded/executed?
          – F. Amg
          Dec 4 at 15:14












          @F.Amg create.js.erb is the view that renders for remote: true requests... if create.js.erb is not working it means that requests may not be rendering as js format and page whole page is being refreshed
          – Sikandar Tariq
          Dec 5 at 6:47




          @F.Amg create.js.erb is the view that renders for remote: true requests... if create.js.erb is not working it means that requests may not be rendering as js format and page whole page is being refreshed
          – Sikandar Tariq
          Dec 5 at 6:47


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53438145%2frails-js-like-button-with-ajax-in-2018%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          What visual should I use to simply compare current year value vs last year in Power BI desktop

          Alexandru Averescu

          Trompette piccolo