【问题标题】:How to optimize a has_many through query in a loop in Rails?如何在 Rails 的循环中通过查询优化 has_many?
【发布时间】:2013-01-22 08:44:50
【问题描述】:

我有两个模型,具有这些关联:

class Product < ActiveRecord::Base
  has_many :side_orders
  has_many :garnishes, :through => :side_orders

  attr_accessible :garnishes_number
end

配菜也是产品,所以是自联的:

class SideOrder < ActiveRecord::Base
  belongs_to :product
  belongs_to :garnish, :class_name => "Product", :foreign_key => "garnish_id"

  attr_accessible :list_number
end

一种产品可能有许多装饰物列表(以便客户在订购一种产品时可以选择不同的装饰物)。每个选择一个列表。一种产品的选择列表不超过“garnishes_number”。

在我的应用程序中,在管理部分,我必须执行以下操作:

<% Product.all.each do |product| %>
  <% for i in 0..(product.garnishes_number - 1) %>
     Lists of garnishes:
     <%= product.garnishes.where("side_orders.list_number = ?", i) %> <br />
  <% end %>
<% end %>

这只是一个例子...问题是 Rails 对每个“i”的值进行一次查询,所以如果一个产品有 8 个列表,Rails 将对数据库执行 8 个查询...当有超过数百个产品,它变得非常慢......

有没有办法优化这样的查询?包含似乎不起作用...如果有人有任何想法或可能有不同的逻辑,请不要犹豫回答。

[编辑] 我想要访问每个装饰物列表这一事实很重要,因为我希望它们以这种方式出现在表格中:

<table>
  <thead>
    <td>Product</td>
    <td>List of garnishes </td>
  </thead>
  <tbody>
    <% Product.all.each do |product| %>
      <% for i in 0..(product.garnishes_number - 1) %>
        <tr>
          <td>product.name</td>
          <td>
              List number <%= i %>: 
              <%= product.garnishes.where("side_orders.list_number = ?", i) %>
          </td>
        </tr>
      <% end %>
    <% end %>
  </tbody>
</table>

我没有把它放在首位,因为我不希望我的问题太长......但是,我认为我应该已经把它写下来,以便我的问题可以更容易理解...... . 对不起^^'

非常感谢! 库尔加。

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 optimization has-many-through self-join


    【解决方案1】:

    您可以通过以下方式进行

    <% Product.all.each do |product| %>
     <% temp = Array.new %>
     <% for i in 0..(product.garnishes_number - 1) %>
       <% temp.push(i) %>
     <%end%>   
      Lists of garnishes:
      <%= product.garnishes.where("side_orders.list_number in(?)", temp ) %> <br />
    <% end %>
    

    这将对每个产品只调用一次 where 查询

    【讨论】:

    • 看起来很棒,但我想在每个装饰列表之间做一个
      ...好吧,我放了一个 br,这样我的例子就不是很大,但实际上它在一个表,每一行显示每个产品一个配菜列表。我会更新我的答案,以便您更好地理解我的意思。
    • 您可以稍后手动完成,因为没有对数据库的查询
    • 什么意思?您能否举一个例子,例如,我如何从查询中获取第一个配菜列表?非常感谢! :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多