我需要使用Ajax按选定的类别显示产品;如果用户没有选择类别,则显示所有产品。如果用户选择了一个或两个类别,则只应显示属于这些类别的产品。
例:
我的模型产品,类别和连接表cause_products
分类
class Category < ActiveRecord::Base
has_and_belongs_to_many :products
end
产品
class Product < ActiveRecord::Base
has_and_belongs_to_many :categories
end
我正在寻找一个教程,我找到了“Rails 4:”How to partials & AJAX, dead easy“。我遵循了这个教程,但是我得到了一个错误。我觉得我错过了什么。
您能否就此提出建议或参考有用的资料来源。谢谢!
产品控制器:
class ProductsController < ApplicationController
def index
@products = Product.all
@categories = Category.all
end
def from_category
@selected = Product.where(:category_id => params[:cat_id])
respond_to do |format|
format.js
end
end
end
产品/ index.html.erb:
<div class="grid">
<%= render 'sidebar_menu' %>
<%= render partial: 'product_grid', locals: { products: @products} %>
</div>
产品/ _sidebar_menu
<% @categories.each do | cat | %>
<%= link_to cat.name, fetch_products_path(:cat_id => cat.id), :remote => true %>
<% end %>
的routes.rb
get "/fetch_products" => 'products#from_category', as: 'fetch_products'
产品/ _products_grid.html.erb
<div>
<%= render partial: 'products_list', locals: { products: products } %>
</div>
产品/ _products_list.html.erb
<% products.each do |product| %>
<div class="product_box">
product.name
</div>
<% end %>
产品/ from_category.js.erb
$("#products_grid").html("<%= escape_javascript(render partial: 'products_list', locals: { products: @selected } ) %>");
我的终端输出:
Product Load (3.2ms) SELECT `products`.* FROM `products` WHERE `products`.`category_id` = '11'
Mysql2::Error: Unknown column 'products.category_id' in 'where clause': SELECT `products`.* FROM `products` WHERE `products`.`category_id` = '11'
Rendered products/_products_list.html.erb (8.8ms)
Rendered products/from_category.js.erb (12.2ms)
Completed 500 Internal Server Error in 23ms (ActiveRecord: 3.5ms)
ActionView::Template::Error (Mysql2::Error: Unknown column 'products.category_id' in 'where clause': SELECT `products`.* FROM `products` WHERE `products`.`category_id` = '11'):
1: <% products.each do |product| %>
2: <div class="product_box">
3: <%= product.name %>
4: </div>
app/views/products/_products_list.html.erb:1:in `_app_views_products__products_list_html_erb___255698018512654633_70336949043820'
app/views/products/from_category.js.erb:1:in `_app_views_products_from_category_js_erb___4172137050793767106_70336965664480'
app/controllers/products_controller.rb:24:in `from_category'`
* - 原来 sidebar_menu文件只包含一行:
<%= link_to cat.name, fetch_items_path(:cat_id => cat.id), :remote => true %>
但是我收到了这个错误:
Showing views/products/_sidebar_menu.html.erb where line #1 raised:
undefined local variable or method `cat' for #<#<Class:0x007ff1336747c0>:0x007ff1350376a8>
Extracted source (around line #1):
<%= link_to cat.name, fetch_products_path(:cat_id => cat.id), :remote
=> true %>
@max的解决方案:
def from_category
@products = Product.joins(:categories).where(categories: { id: params[:cat_id] })
respond_to do |format|
format.js
end
感谢 @max 的帮助,他的解决方案是更新控制器操作,它解决了错误,但选择类别后产品列表没有刷新。
日志:
Started GET "/fetch_products?cat_id=11" for ::1 at 2016-04-18 13:53:01 +0300
Processing by ProductsController#from_category as JS
Parameters: {"cat_id"=>"11"}
Product Load (1.9ms) SELECT `products`.* FROM `products` INNER JOIN `categories_products` ON `categories_products`.`product_id` = `products`.`id` INNER JOIN `categories` ON `categories`.`id` = `categories_products`.`category_id` WHERE `categories`.`id` = 11
Rendered products/_products_list.html.erb (6.4ms)
Rendered products/from_category.js.erb (11.5ms)
Completed 200 OK in 29ms (Views: 24.1ms | ActiveRecord: 1.9ms)
@max这是我点击某个类别时在响应中得到的结果:
$("#products_grid").html("
<div class=\"product_box\">\n Bed\n <\/div>\n
<div class=\"product_box\">\n Notebook\n <\/div>\n
<div class=\"product_box\">\n Desk\n <\/div>\n
<div class=\"product_box\">\n Mug\n <\/div>\n"
);
@Jeffrey M Castro注意到我错过了products_grid
中的div
ID:
产品/ _products_grid.html.erb
<div id="products_grid">
<%= render partial: 'products_list', locals: { products: products } %>
</div>
该代码仅适用于所选类别,但我希望它能够过滤两个或更多类别。我需要做出哪些改变?
方案: 用户点击“主页类别”,即可获得属于此类别的所有产品。然后他点击“鞋子类别”,现在他看到属于这两个类别的所有产品(“家庭类别”或“鞋子类别”)。用户点击“全部清除”按钮(为了重置所选类别),现在显示所有类别的所有产品。
感谢。
答案 0 :(得分:2)
由于产品和类别之间存在has_and_belongs_to_many
关系,因此您无法按products.category_id
选择产品,因为两者之间的实际链接存储在categories_products
联接表中。
您需要使用联接并在关联中指定条件:
@products = Product.joins(:categories)
.where(categories: { id: params[:cat_id] })
答案 1 :(得分:2)
根据@max的回复,最好使用浏览器检查器的网络选项卡检查服务器提供的JS响应。
在您的代码中:
$("#products_grid").html("<%= escape_javascript(render partial: 'products_list', locals: { products: @selected } ) %>");
您想要更改#products_grid
的html内容,但我在您的视图文件中没有看到任何具有该ID的内容。
因此,您必须在div中指定其ID为#products_grid
:
products / _products_grid.html.erb
<div id="products_grid">
<%= render partial: 'products_list', locals: { products: products } %>
</div>