Rails: добавьте продукт в избранное и используйте ajax для кнопки «Избранное» / «Избранное» - PullRequest
0 голосов
/ 04 марта 2019

Я перебираю ряд продуктов и разрываю кнопку «Избранное» / «Избранное» рядом с каждым продуктом:

<% @products.each do |product| %>
<%= product.title %>
<%= product.price %>
<%= product.description %>

<div id="favorites_grid">
  <%= render partial: 'favorite_products/favorite', locals: { product: product } %>
</div>

Часть с любимыми кнопками _favorite.html.erb:

<% unless current_user.favorite_products.exists?(product.id) %>
  <%= link_to "Favorite", create_favorited_product_path(product_id: product.id), method: :post, :remote => true %>
<% else %>
  <%= link_to "Unfavorite", favorited_product_path(product_id: product.id), method: :delete, :remote => true %>
<% end %>

Схема таблицы:

class CreateFavorites < ActiveRecord::Migration
  def change
    create_table :favorites do |t|
      t.references :favorited, polymorphic: true, index: true
      t.references :user, index: true

      t.timestamps
    end
  end
end

Ассоциации моделей:

class Favorite < ApplicationRecord
  belongs_to :user
  belongs_to :favorited, polymorphic: true
end

class Consumer < ApplicationRecord
  has_many :favorites
  has_many :favorite_products, through: :favorites, source: :favorited, source_type: 'Product'
end

Контроллер:

def create
  @favorite = Favorite(favorited: @product, user_id: current_user.id)
    respond_to do |format|
      if @ favorite.save
        flash.now[:success] = "You have successfully added this product to your favorites list."
        format.js { render 'favorite.js.erb' }
      else
        flash.now[:alert] = "Something when wrong!"
        format.js { render 'favorite.js.erb' }
      end
    end
end

def destroy
  @favorite = Favorite.where(favorited_id: @product.id, user_id: current_user.id)
  respond_to do |format|
    @favorite.first.destroy
    flash.now[:success] = "You have successfully removed this product from your favorites list."
    format.js { render 'favorite.js.erb' }
  end
end

У меня отключены турболинии.

The favourite.js.erb:

$('#favorites_grid').html("<%= escape_javascript(render partial: 'favorite_products/favorite', locals: { product: @product } ) %>");
$("#flash").html("<%= escape_javascript(render partial: 'layouts/messages') %>");

И маршруты:

post 'favorite_products', to: 'favorite_products#create', defaults: { format: 'js' }, :as => 'create_favorited_product'
delete 'favorite_products/id', to: 'favorite_products#destroy', defaults: { format: 'js' }, :as => 'favorited_product'

Кнопка «Избранное» / «Избранное» правильно отображает рядом с каждым продуктом назагрузка первой страницы.Кроме того, кнопка работает просто отлично, она выбирает / удаляет продукт, с которым она связана.

Единственная проблема, с которой я сталкиваюсь, заключается в том, что ... если я нажимаю на любой продукт, чтобы добавить его в избранное или нет, ajaxбудет отображать первую кнопку как любимую / не любимую.Другими словами, ajax не передает правильную кнопку в соответствии с текущим статусом (избранным или избранным).Если я обновляю страницу, все отображается правильно.

Любые идеи о том, как я могу решить эту проблему?

1 Ответ

0 голосов
/ 04 марта 2019

Таким образом, ваша проблема заключается в помещении <div id="favorites_grid"> в цикл продукта, что приводит к наличию нескольких элементов div с одинаковым id.Затем, когда вы ищите div для замены, вы всегда получаете первый заменяющий.

Мое предложение

<% @products.each do |product| %>
  <%= product.title %>
  <%= product.price %>
  <%= product.description %>

  <div id="favorites_grid_<%= product.id %>">
    <%= render partial: 'favorite_products/favorite', locals: { product: product } %>
  </div>
<% end %>

Тогда вы можете посмотреть точную сетку, полагаясь на favorites_grid_#{product.id}внутри вашего favorite.js.erb

Попробуйте обновить:

$("#favorites_grid_<%= @product.id %>").html("<%= escape_javascript(render partial: 'favorite_products/favorite', locals: { product: @product } ) %>");
$("#flash").html("<%= escape_javascript(render partial: 'layouts/messages') %>");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...