我有一个带有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
如果您需要任何其他信息,请告诉我,谢谢!
答案 0 :(得分:1)
在这里,我使用的是一种方法,因为你从不希望喜欢的数量低于零。
每当用户喜欢帖子时,计数增加1并且竖起大拇指图标的颜色会发生变化(仅显示视觉变化)。
当用户点击已经喜欢的帖子时,喜欢的数量应该减少一个,所以我们应该使用gem提供的 unliked_by 方法。
为了实现这一点,我们可以使用upvote.js.erb文件(记住文件名应该与控制器方法名称相同,这样可以简化过程)。
然后在.js.erb
文件中,我们可以将ruby
与js
混合,并获得upvote.js.erb
文件中显示的所需结果。
我添加了一个名为liked
的额外类,它改变了按钮的颜色。
请注意:我假设您在一个页面上有一个帖子。如果您在网页上有多个帖子,那么您应该将ID添加到帖子容器中,同样更改js
文件中的upvote.js.erb
代码。
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
<% 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 %>";
<!-- 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>