简体   繁体   English

Rails Acts_as_votable Gem Like /与Ajax不同的按钮

[英]Rails Acts_as_votable Gem Like/Unlike Buttons with Ajax

I'm new to Ruby On Rails, I used the acts_as_votable gem to create Like and Unlike Buttons to make Users like and unlike Posts but I can't make them change from Like to Unlike (and viceversa) and update the counter each time they click without refreshing the page. 我是Ruby On Rails的新手,我使用acts_as_votable gem来创建Like和不同的按钮,使用户喜欢和不像Posts但我不能让他们从Like变为不同(和反之)并且每次他们更新计数器单击而不刷新页面。 I tried following other kind-of-similar answers but I had no luck. 我尝试过其他类似的答案,但我没有运气。 Without the messy changes I tried to do to implement Ajax my code looked like this: 没有我试图实现Ajax的混乱更改,我的代码看起来像这样:

Post Model acts_as_votable and User Model acts_as voter 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

Routes have 路线有

resources :posts do
  member do
    put 'like', to: "posts#like"
    put 'unlike', to: "posts#unlike"
  end
end

View has 查看了

<%= @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>

I read a lot of answers about Ajax but I was unable to replicate the results. 我阅读了很多关于Ajax的答案,但我无法复制结果。 Thank you in advance! 先感谢您!

First, you need to point out your posts controller to respond to js format . 首先,您需要指出您的帖子控制器以响应js格式 Then the two actions in posts_controller become: 然后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

Second, you need to pass remote: true on your links: 其次,您需要在链接上传递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>

I change method: :put to method: :get , so change it in your config/routes.rb , and add a class to your links to bind it in js. 我更改method: :put to method: :get ,所以在config/routes.rb更改它,并在链接中添加一个以在js中绑定它。

Finally, you need to create 2 views in app/views/posts/ : 最后,您需要在app/views/posts/创建2个视图:

  • like.js.erb 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.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' %>'); }); 

To handle update of count, I use a .vote_count class, so in your view: 要处理计数更新,我使用.vote_count类,因此在您的视图中:

<div class="vote_count">
  <%= @post.get_likes.size %>
</div> 

So my view: 所以我的看法:

<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>

Edit: I edit my answer. 编辑:我编辑我的答案。 Update your links with class instead id. 使用class而不是id更新您的链接。 And take a look at 2 js view to find closest() . 并查看2 js视图以找到最近的() It works well in index and show page in my sandbox app. 它适用于我的沙盒应用程序中的索引显示页面。 So feel free to adapt to your markup. 所以请随意适应您的标记。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM