Rails Acts_as_votable ajax/js - голосование за все сообщения вместо одного
Хорошо, я начинаю вырывать свои волосы на этом. Я новичок в рельсах, и следовал учебному пособию по созданию приложения в стиле писк. Я закончил это, но не был доволен системой голосования.
Это обновляло страницу каждый раз, когда я нажимал, чтобы проголосовать. Так что я нашел какой-то пост об этом и сделал именно то, что он сказал. Он продолжал загружать страницу, которая показывала мне код js вместо того, чтобы выполнять его.
Этим утром я изменил "положить" на "получить", а затем снова, и теперь он работает... НЕТ ИДЕИ, что случилось, чтобы изменить его.
НО, теперь он голосует за каждый пост на странице, а не за тот, который я нажимаю. Когда я наводю указатель мыши на ссылки, все они указывают на правильный идентификатор этой ссылки.
Вот код из контроллера:
def upvote
@pin.upvote_by current_user
respond_to do |format|
format.html { redirect_to :back }
format.js { render :layout => false }
format.json
end
end
И мнение (хамл):
.btn-group.pull-right
= link_to like_pin_path(pin), method: :put, remote: true, class: "btn btn-like" do
%span.glyphicon.glyphicon-heart
= pin.get_upvotes.size
Upvote.js.erb:
$('.glyphicon-heart').html('<%=@pin.get_upvotes.size%>');
routes.rb
Rails.application.routes.draw do
devise_for :users
resources :pins do
member do
put "like", to: "pins#upvote", defaults: { format: 'js' }
end
end
root "pins#index"
end
Вот журнал из консоли, когда нажимается кнопка "Мне нравится":
Started PUT "/pins/10/like" for ::1 at 2015-12-08 11:40:02 -0600
Processing by PinsController#upvote as JS
Parameters: {"id"=>"10"}
Pin Load (0.2ms) SELECT "pins".* FROM "pins" WHERE "pins"."id" = ? LIMIT 1 [["id", 10]]
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 2]]
(0.3ms) SELECT COUNT(*) FROM "votes" WHERE "votes"."votable_id" = ? AND "votes"."votable_type" = ? AND "votes"."voter_id" = ? AND "votes"."voter_type" = ? AND "votes"."vote_scope" IS NULL [["votable_id", 10], ["votable_type", "Pin"], ["voter_id", 2], ["voter_type", "User"]]
ActsAsVotable::Vote Load (0.6ms) SELECT "votes".* FROM "votes" WHERE "votes"."votable_id" = ? AND "votes"."votable_type" = ? AND "votes"."voter_id" = ? AND "votes"."voter_type" = ? AND "votes"."vote_scope" IS NULL ORDER BY "votes"."id" DESC LIMIT 1 [["votable_id", 10], ["votable_type", "Pin"], ["voter_id", 2], ["voter_type", "User"]]
(0.2ms) begin transaction
(0.1ms) commit transaction
(0.2ms) SELECT COUNT(*) FROM "votes" WHERE "votes"."votable_id" = ? AND "votes"."votable_type" = ? AND "votes"."vote_flag" = ? AND "votes"."vote_scope" IS NULL [["votable_id", 10], ["votable_type", "Pin"], ["vote_flag", "t"]]
Rendered pins/upvote.js.erb (4.4ms)
Completed 200 OK in 25ms (Views: 9.4ms | ActiveRecord: 1.8ms)
Я уверен, что это что-то действительно простое, но ajax/js для меня даже новее, чем рельсы.
Дайте мне знать, если есть что-то еще, что мне нужно опубликовать. Любая помощь будет очень признательна!
Также для дальнейшего использования, что заставило бы ссылку загружать страницу с кодом js вместо выполнения кода? Поскольку я не чувствую, что изменил что-то столь радикальное сегодня, я не знаю, как мне это удалось. Я рад, что сделал, но было бы полезно узнать, КАК.
1 ответ
Это происходит потому, что ваш JS технически нацелен на все ссылки с этим классом. Вместо этого вы можете добавить модель id
индивидуальный контакт для класса ссылки или создать атрибут данных, но это полностью зависит от вас. При этом он будет ориентирован только на одну ссылку, на которую нажали.
ОБНОВИТЬ:
По сути, вы захотите назначить класс (идентификатор экземпляра) для контейнера div с кнопкой голосования: pin-#{pin.id}
для просмотра индекса и pin-#{@pin.id}
для просмотра.
контроллер
def upvote
@pin.upvote_by current_user
respond_to do |format|
format.js { render "upvote.js.erb" }
end
end
Маршруты
...
resources :pins do
member do
put :upvote
end
end
Индекс
...
%div{class: "btn-group pull-right pin-#{pin.id}"}
= render "upvote", pin: pin
Показать представление
...
.col-md-6
%div{class: "btn-group pull-right pin-#{@pin.id}"}
= render "upvote", pin: @pin
-if user_signed_in?
= link_to "Edit", edit_pin_path, class: "btn btn-default"
= link_to "Delete", pin_path, method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-default"
_upvote.html.haml
= link_to upvote_pin_path(pin), method: :put, remote: :true, class: "btn btn-default btn-like" do
%span.glyphicon.glyphicon-heart
= pin.get_upvotes.size
upvote.js.erb
$(".pin-<%= @pin.id %>").html("<%= escape_javascript(render 'upvote', pin: @pin) %>");