Rails:收藏产品,并使用ajax作为收藏/不喜欢按钮

时间:2019-03-04 09:28:59

标签: ruby-on-rails ajax

我正在浏览一系列产品,并在每个产品旁边添加“收藏夹” /“收藏夹”按钮:

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

我禁用了涡轮链接。

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 :(得分:1)

因此,您的问题是将<div id="favorites_grid">放入产品循环中,这导致多个div具有相同的id。然后,当您查找要替换的div时,总是得到第一个要替换的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') %>");