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) %>");
Другие вопросы по тегам