我是Ruby On Rails的新手,我使用acts_as_votable gem来创建喜欢和不喜欢的按钮,让用户喜欢和不喜欢的帖子,但我不能让他们从喜欢到不喜欢(反之亦然),并且每次点击时更新计数器而不刷新页面。我试着遵循其他类似的答案,但我没有运气。如果没有我试图实现Ajax所做的混乱的更改,我的代码看起来像这样:
Post Model acts_as_votable和User Model acts_as voter
Posts Controller has
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的答案,但我无法复制结果。提前感谢!
首先,您需要指出您的posts控制器来响应js格式。那么posts_controller
中的两个动作变成:
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
中更改它,并添加类到您的链接中绑定它。
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' %>'); });
unlike.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>
编辑:我编辑我的答案。用class代替id更新链接。并看看2js视图找到最接近()。在我的沙箱应用中,它在index和show页面中工作得很好。所以请随意调整您的标记