4

我是 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 的答案,但我无法复制结果。先感谢您!

4

1 回答 1

1

首先,您需要指出您的帖子控制器以响应 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, 中改一下 , 给你的链接添加一个来绑定到 js 中。

最后,您需要在以下位置创建 2 个视图app/views/posts/

  • 像.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 视图以找到最接近的()。它在我的沙盒应用程序的索引显示页面中运行良好。因此,请随时适应您的标记。

于 2015-07-06T20:12:06.327 回答