Rails Acts_as_votable Gem Like/Unlike Кнопки с Ajax
Я новичок в Ruby On Rails, я использовал гем act_as_votable для создания кнопок "Мне нравится" и "Не нравится", чтобы сделать пользователей "похожими" на "Посты", но я не могу изменить их с "Нравится" на "Не нравится" (и наоборот) и обновлять счетчик каждый раз, когда они нажмите, не обновляя страницу. Я пытался следовать другим подобным ответам, но мне не повезло. Без грязных изменений, которые я пытался реализовать для реализации Ajax, мой код выглядел так:
Опубликовать модель act_as_votable и пользовательскую модель актов_as избиратель
Контроллер сообщений имеет
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 ответ
Во-первых, вам нужно указать свой контроллер сообщений для ответа в формате 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/
:
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>
Редактировать: я редактирую свой ответ. Обновите ваши ссылки с классом вместо идентификатора. И посмотрите на 2 js view, чтобы найти ближайший (). Это хорошо работает в индексной и показывать страницу в моем приложении песочницы. Так что не стесняйтесь адаптироваться к вашей разметке.