如何使这个代码更干燥

时间:2016-05-21 09:07:39

标签: ruby-on-rails postgresql haml

我想知道是否可以使这段代码更简单。我担心使用相同的查询多次访问数据库。这是我的代码:

#hot-panel.mdl-tabs__panel.is-active
 %ul.product-list-three.mdl-list
  - @merchant.products.where('products.prototype_id = 1').select(&:id).flatten.uniq.each do |item|
   = render :partial => 'product', :locals => {:item => item }
#cold-panel.mdl-tabs__panel
 %ul.product-list-three.mdl-list
  - @merchant.products.where('products.prototype_id = 2').select(&:id).flatten.uniq.each do |item|
   = render :partial => 'product', :locals => {:item => item }

以下是日志:

Product Load (1.1ms)  SELECT "products".* FROM "products" INNER JOIN "variants" ON "products"."id" = "variants"."product_id" INNER JOIN "variant_merchants" ON "variants"."id" = "variant_merchants"."variant_id" WHERE "variant_merchants"."merchant_id" = $1 AND (products.prototype_id = 1)  [["merchant_id", 1]]
default_url_options is passed options: {}

  Rendered shopping/merchants/_product.html.haml (3.5ms)
  Product Load (1.2ms)  SELECT "products".* FROM "products" INNER JOIN "variants" ON "products"."id" = "variants"."product_id" INNER JOIN "variant_merchants" ON "variants"."id" = "variant_merchants"."variant_id" WHERE "variant_merchants"."merchant_id" = $1 AND (products.prototype_id = 2)  [["merchant_id", 1]]
  Rendered shopping/merchants/_product.html.haml (0.5ms)

模型 商户

 has_many :variant_merchants
 has_many :variants, through: :variant_merchants, dependent: :destroy
 has_many :products, through: :variants, dependent: :destroy

产品

 belongs_to :prototype
 has_many :product_properties
 has_many :properties, through: :product_properties

 has_many :variants, dependent: :destroy

变体

 has_many :variant_merchants, dependent: :destroy
 has_many :merchants, through: :variant_merchants

 has_many :variant_properties
 has_many :properties, through: :variant_properties

产品部分

= link_to shopping_merchant_product_path(@merchant, item.id) do
  %li.mdl-list__item.mdl-list__item--three-line
    %span.mdl-list__item-primary-content
      %span= item.name
      %span.mdl-list__item-text-body
        = item.description
    %span.mdl-list__item-secondary-content
      %i.material-icons
        chevron_right

1 个答案:

答案 0 :(得分:1)

在你的控制器中你可以创建一个像

这样的变量
@merchant_product_lists = @merchant.products.where("products.prototype_id" => [1, 2]).group_by(&:prototype_id)

然后在你看来

#hot-panel.mdl-tabs__panel.is-active
 %ul.product-list-three.mdl-list
  = render partial: 'product', collection: @merchant_product_lists[1]
#cold-panel.mdl-tabs__panel
 %ul.product-list-three.mdl-list
  = render partial: 'product', collection: @merchant_product_lists[2]

@merchant.products.where("products.prototype_id" => [1, 2]).group_by(&:prototype_id)只会调用一次数据库,并使用ruby方法group_by将结果按products.prototype_id分组,当您显示时,它会为您提供哈希映射prototype_id to products它们在视图中,您只需要调用相应的prototype_id来检索产品