轨道与Ajax:按选定的过滤器显示产品 [英] Rails & Ajax: display products by chosen filters
问题描述
我需要使用Ajax按选定类别显示产品;如果用户未选择类别,则显示所有产品.如果用户选择一个或两个类别,则仅应显示属于这些类别的产品.
例子:
我的模型产品",类别"和联接"表Causes_products
I need to display products by chosen categories using Ajax; if the user didn't choose a category, then all the products are displayed. If the user chose one or two categories, then only products that belong to these categories should be displayed.
Example:
My models Product, Category, and join table causes_products
类别
class Category < ActiveRecord::Base
has_and_belongs_to_many :products
end
class Category < ActiveRecord::Base
has_and_belongs_to_many :products
end
产品
class Product < ActiveRecord::Base
has_and_belongs_to_many :categories
end
class Product < ActiveRecord::Base
has_and_belongs_to_many :categories
end
我在寻找教程时,发现"Rails 4:"
您能在这方面给我建议还是参考有用的资源?谢谢!
I was looking for a tutorial and I found "Rails 4: "How to partials & AJAX, dead easy". I followed this tutorial but I got an error. I feel like I missed something.
Can you please advise me on this or refer to a helpful source. Thank you!
产品控制器:
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
products/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/_products_grid.html.erb
<div>
<%= render partial: 'products_list', locals: { products: products } %>
</div>
products/_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 %>
但是我得到了这个错误:
* - originally sidebar_menu file contained only one line:
<%= link_to cat.name, fetch_items_path(:cat_id => cat.id), :remote => true %>
but I got this error:
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 的帮助,他的解决方案是更新控制器操作,它解决了该错误,但选择类别后未刷新产品列表.
Thanks to @max for his help, his solution was to update controller action, it solved the error but the list of products isn't being refreshed after selecting a category.
日志:
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,这是我在单击类别时得到的响应:
@max That's what I get in the response when I click on a category:
$("#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发现我在div
中缺少products_grid
id:
@Jeffrey M Castro noticed that I was missing the products_grid
id in the div
:
products/_products_grid.html.erb
<div id="products_grid">
<%= render partial: 'products_list', locals: { products: products } %>
</div>
该代码仅对一个选定的类别有效,但我希望它也能够过滤两个或多个类别.我需要进行哪些更改?
场景: 用户单击家庭类别",他将获得属于该类别的所有产品.然后,他单击鞋子类别",现在他看到属于这两个类别的所有产品(家庭类别"或鞋子类别").用户单击全部清除"按钮(以重置所选类别),现在将显示所有类别的所有产品.
Scenario: User clicks the 'Home category', he gets all the products that belong to this category. Then he clicks on the 'Shoes category' and now he sees all the products that belong to both categories ('Home category' or 'Shoes category'). User clicks on the 'Clear All' button (in order to reset the chosen categories), now all the products from all the categories are displayed.
谢谢.
推荐答案
由于产品和类别之间具有has_and_belongs_to_many
关系,因此无法按products.category_id
选择产品,因为两者之间的实际链接存储在
Since you have a has_and_belongs_to_many
relation between products and categories you cannot select products by products.category_id
since the actual link between the two is stored in the categories_products
join table.
您需要使用联接并在关联上指定条件:
You need to use a join and specify the condition on the association instead:
@products = Product.joins(:categories)
.where(categories: { id: params[:cat_id] })
这篇关于轨道与Ajax:按选定的过滤器显示产品的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!