Rails Acts_as_votable Gem Like/Unlike 按钮与 Ajax
Posted
技术标签:
【中文标题】Rails Acts_as_votable Gem Like/Unlike 按钮与 Ajax【英文标题】:Rails Acts_as_votable Gem Like/Unlike Buttons with Ajax 【发布时间】:2015-09-23 22:02:42 【问题描述】:我是 Ruby On Rails 的新手,我使用acts_as_votable gem 来创建喜欢和不喜欢按钮来让用户喜欢和不喜欢帖子,但我不能让它们从喜欢变成不喜欢(反之亦然)并更新计数器每次他们点击而不刷新页面。我尝试遵循其他类似的答案,但我没有运气。 如果没有我试图实现 Ajax 的混乱更改,我的代码如下所示:
发布模型acts_as_votable 和用户模型acts_as voter
帖子控制器有
def like
@post = Post.find(params[:id])
@post.liked_by current_user
redirect_to :back
end
def unlike
@post = Post.find(params[:id])
@post.unliked_by current_user
redirect_to :back
end
路线有
resources :posts do
member do
put 'like', to: "posts#like"
put 'unlike', to: "posts#unlike"
end
end
查看有
<%= @post.get_likes.size%>
<% if @post.get_likes.size ==1 %>
person like this
<% else %>
people like this
<% end %>
<div class="btn-group">
<% if (current_user.liked? @post) %>
<%= link_to unlike_post_path(@post), method: :put, class: "btn btn-default btn-sm" do %>
<span class="glyphicon glyphicon-chevron-down"></span>
Unlike
<%end %>
<% else %>
<%= link_to like_post_path(@post), method: :put, class: "btn btn-primary btn-sm" do %>
<span class="glyphicon glyphicon-chevron-up"></span>
Like
<% end %>
<% end %>
</div>
我阅读了很多关于 Ajax 的答案,但我无法复制结果。 先感谢您!
【问题讨论】:
【参考方案1】:首先,您需要指出您的 posts 控制器以响应 js 格式。那么posts_controller
中的两个action就变成了:
def like
@post = Post.find(params[:id])
@post.liked_by current_user
respond_to do |format|
format.html redirect_to :back
format.js render layout: false
end
end
def unlike
@post = Post.find(params[:id])
@post.unliked_by current_user
respond_to do |format|
format.html redirect_to :back
format.js render layout: false
end
end
其次,您需要在链接上传递remote: true
:
<div class="votes">
<% if current_user.liked? @post %>
<%= link_to unlike_post_path(@post), method: :get, remote: true, class: 'unlike_post' %>
<% else %>
<%= link_to like_post_path(@post), method: :get, remote: true, class: 'like_post' %>
<% end %>
</div>
我把method: :put
改成method: :get
,所以在你的config/routes.rb
里改一下,并在你的链接中添加一个class来绑定到js中。
最后,你需要在app/views/posts/
中创建2个视图:
like.js.erb
$('.like_post').bind('ajax:success', function()
$(this).parent().parent().find('.vote_count').html('<%= escape_javascript @post.votes_for.size.to_s %>');
$(this).closest('.like_post').hide();
$(this).closest('.votes').html(' <%= link_to "Unlike", unlike_post_path(@post), remote: true, method: :get, class: 'unlike_post' %>');
);
不像.js.erb
$('.unlike_post').bind('ajax:success', function()
$(this).parent().parent().find('.vote_count').html('<%= escape_javascript @post.votes_for.size.to_s %>');
$(this).closest('.unlike_post').hide();
$(this).closest('.votes').html(' <%= link_to "Like", like_post_path(@post), remote: true, method: :get, class: 'like_post' %>');
);
为了处理计数的更新,我使用了.vote_count
类,所以在您看来:
<div class="vote_count">
<%= @post.get_likes.size %>
</div>
所以我的看法:
<div>
<div class="vote_count">
<%= @post.get_likes.size %>
</div>
<div class="votes">
<% if current_user.liked? @post %>
<%= link_to unlike_post_path(@post), method: :get, remote: true, class: 'unlike_post' %>
<% else %>
<%= link_to like_post_path(@post), method: :get, remote: true, class: 'like_post' %>
<% end %>
</div>
</div>
编辑:我编辑我的答案。使用类而不是 id 更新您的链接。并查看 2 js 视图以找到 closest()。它在我的沙盒应用程序的 index 和 show 页面中运行良好。因此,请随时适应您的标记。
【讨论】:
非常感谢!我有点明白它现在是如何工作的,所以我必须将我的路线更改为 get 'like',以:"posts#like" 获取 'unlike',以:"posts#unlike" 但是当你说 "add an id to在 js 中绑定”我应该在哪里/如何执行此操作? 只有那个?我认为还有其他事情要做,因为我有“未定义的局部变量或方法 `like_post'”(和不一样的_post) 应该是 id: 'like_post' 和 ' ' 吗? 很抱歉再次打扰您。以前,我曾经能够使用类似的视图为 Feed 中的每个帖子单独激活按钮,而不是 @post 和 link_to 内的构造“do-end”,但现在当我单击一个按钮时,它会全部更改提要中的其他按钮(和计数)(像 facebook 墙之类的东西)和第一个“喜欢”之后,当我将鼠标悬停在每个不同的按钮上时,它会为每个帖子显示相同的 post.id(但只有第一个按钮有效) 在我的回答中查看我的编辑部分。如果您有任何问题,请告诉我。我也可以和你分享我的沙盒应用。以上是关于Rails Acts_as_votable Gem Like/Unlike 按钮与 Ajax的主要内容,如果未能解决你的问题,请参考以下文章