在Rails应用程序中将ajax添加到like按钮

时间:2016-10-21 03:07:05

标签: ruby-on-rails

我有一个带有Post资源的rails应用程序,其中每个特定帖子都可以被喜欢/不喜欢。

我希望能够在不刷新页面的情况下喜欢/不喜欢某些内容。我已经查看了其他一些SO帖子,所有答案都涉及Coffeescript,我怎样才能用vanilla js解决这个问题?

(我正在使用Friendly_id和acts_as_votable gems)

控制器

 class PostsController < ApplicationController
    before_action :authenticate_user!, only: [:upvote, :downvote] 
    before_action :set_post, only: [ :show , :upvote, :downvote] 
    respond_to :js, :json, :html

  def upvote
    @post.liked_by current_user
    redirect_back(fallback_location: root_path) 
  end 

  def downvote
    @post.disliked_by current_user
    redirect_back(fallback_location: root_path) 
  end 

end

查看

 <%= link_to like_post_path(@post), 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 %> 
      <%= link_to dislike_post_path(@post), class:"dislike-btn", method: :put, remote: true do %> 
        <button class="btn btn-warning"> 
          <span><p><i class="fa fa-thumbs-down fa-lg" aria-hidden="true"></i></p></span>
        </button> 
      <% end %> 
      <span> <%= @post.get_upvotes.size %> </span> 

路线

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

模型

class Post < ApplicationRecord
  acts_as_votable

  extend FriendlyId
  friendly_id :title, use: :slugged 
end


  class User < ApplicationRecord
  acts_as_voter
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
end

如果您需要任何其他信息,请告诉我,谢谢!

1 个答案:

答案 0 :(得分:1)

在这里,我使用的是一种方法,因为你从不希望喜欢的数量低于零。

每当用户喜欢帖子时,计数增加1并且竖起大拇指图标的颜色会发生变化(仅显示视觉变化)。

当用户点击已经喜欢的帖子时,喜欢的数量应该减少一个,所以我们应该使用gem提供的 unliked_by 方法。

为了实现这一点,我们可以使用upvote.js.erb文件(记住文件名应该与控制器方法名称相同,这样可以简化过程)。

然后在.js.erb文件中,我们可以将rubyjs混合,并获得upvote.js.erb文件中显示的所需结果。

我添加了一个名为liked的额外类,它改变了按钮的颜色。

请注意:我假设您在一个页面上有一个帖子。如果您在网页上有多个帖子,那么您应该将ID添加到帖子容器中,同样更改js文件中的upvote.js.erb代码。

posts_controller.rb

  def upvote
    if !current_user.liked? @post
      @post.liked_by current_user
    elsif current_user.liked? @post
      # as the above method can also result nil if he is yet to vote
      @post.unliked_by current_user 
    end
  end 

视图/帖/ upvote.js.erb

<% if current_user.liked? @post %>
 document.getElementsByClassName('like-btn')[0].className = "like-btn liked";
<% else %>
 document.getElementsByClassName('like-btn')[0].className = "like-btn";
<% end %>
document.getElementsByClassName('likes-count')[0].innerHTML="<%= @post.get_upvotes.size %>";

view.html.erb

<!-- Adding a class liked -->
<style>
 .liked {
    color: blue;
  }
</style>
<%= link_to like_post_path(@post), 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"> <%= @post.get_upvotes.size %> </span>