在视图或控制器中分组

时间:2016-04-19 12:56:39

标签: ruby-on-rails activerecord group-by grouping

我正在尝试遍历供应商通过其不同变体销售的产品列表。我可以获得要显示的产品列表,但我希望按产品ID对这些产品进行分组,只显示一次。

在我的控制器里我有

@supplier = Supplier.joins(products: :variants).find(params[:id])

在我看来我有

- @supplier.variants.group_by(&:product_id).each do |product_id, item|
    = render :partial => 'product', :locals => {:item => item }

和我的部分

= link_to shopping_supplier_path(item) do
  %li.mdl-list__item.mdl-list__item--three-line
    %span.mdl-list__item-primary-content
      %span= item.product.name
      %span.mdl-list__item-text-body
        = item.product.description.downcase
    %span.mdl-list__item-secondary-content
      %i.material-icons
        chevron_right
    %hr

当sql执行时返回以下查询

    Started GET "/shopping/suppliers/latte-cartelle-drive-thru-coffee-241---245-princes-hwy--ha-1" for 127.0.0.1 at 2016-04-19 23:22:08 +1000
Processing by Shopping::SuppliersController#show as HTML
  Parameters: {"id"=>"latte-cartelle-drive-thru-coffee-241---245-princes-hwy--ha-1"}
  User Load (0.6ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1  ORDER BY "users"."id" ASC LIMIT 1  [["id", 1]]
  Supplier Load (32.7ms)  SELECT  "suppliers".* FROM "suppliers" WHERE "suppliers"."permalink" = $1  ORDER BY "suppliers"."id" ASC LIMIT 1  [["permalink", "latte-cartelle-drive-thru-coffee-241---245-princes-hwy--ha-1"]]
  Supplier Load (41.9ms)  SELECT  "suppliers".* FROM "suppliers" INNER JOIN "variant_suppliers" ON "variant_suppliers"."supplier_id" = "suppliers"."id" INNER JOIN "variants" ON "variants"."id" = "variant_suppliers"."variant_id" INNER JOIN "products" ON "products"."id" = "variants"."product_id" INNER JOIN "variants" "variants_products" ON "variants_products"."product_id" = "products"."id" WHERE "suppliers"."permalink" = $1  ORDER BY "suppliers"."id" ASC LIMIT 1  [["permalink", "latte-cartelle-drive-thru-coffee-241---245-princes-hwy--ha-1"]]
  Variant Load (0.9ms)  SELECT "variants".* FROM "variants" INNER JOIN "variant_suppliers" ON "variants"."id" = "variant_suppliers"."variant_id" WHERE "variant_suppliers"."supplier_id" = $1  [["supplier_id", 1]]
  Rendered shopping/suppliers/_product.html.haml (53.5ms)

错误

NoMethodError at /shopping/suppliers/latte-cartelle-drive-thru-coffee-241---245-princes-hwy--ha-1
undefined method `name' for #<Array:0x007faa5302d5a0>

1 个答案:

答案 0 :(得分:0)

使用SQL joins。当您创建连接要使用的表的查询时,它们将先前加载到内存中,因此不会发生着名的n+1查询。

@supplier = Supplier.joins(variants: :products).find(params[:id])

# This will translate to something like this
SELECT * FROM suppliers
INNER JOIN variants ON variants.supplier_id = suppliers.id
INNER JOIN products ON products.variant_id = variants.id
WHERE suppliers.id = ?

请记住始终避免延迟加载您的关联。

相关问题