在Rails 4中优化数据库查询

时间:2014-01-03 20:15:48

标签: ruby-on-rails activerecord ruby-on-rails-4

我在视图中有以下代码,列出了所有客户以及每个客户订单的总金额。

实体类型Customer,Order和OrderItem之间的关系是:Customer-1:n-Order-1:n-OrderItem

view index.rb

<% @customers.each do |c| %>
 <tr>
   <td id="name"><%= c.name %>
   <td id="cus_total"><%= c.orders.map(&:order_total_amount).sum %>
 </tr>

customers_controller.rb

@customers = Customer.find(:all)

model orders.rb

def order_total_amount
 orderitems.sum("amount")
end

我现在想要打印表格第一行中所有客户的所有订单总金额。显然,我不想再次查询DB以完成此任务,因为总金额只是“cus_total”列中所有项目的总和。 如果我想打印表格底部的总金额,我只会做

<% @customers.each do |c| %>
 <tr>
  <td id="name"><%= c.name %>
  <td id="cus_total"><%= total += c.orders.map(&:order_total_amount).sum %>
 </tr>
<% end %>
 <tr>
  <td>Total</td>
  <td><%= total %></td>
 </tr>

但是当我想在表格的顶部打印总金额而不再查询数据库时,我在Rails 4中该怎么办?

2 个答案:

答案 0 :(得分:2)

我看到很多方法可以达到你想要的结果,但我离开了你这里可能的方法:

我会使用callback来保存和更新 total_orders中每个客户的订单总和(您只需要在客户模型中添加一列

  

rails g migration AddTotalOrdersToCustomers total_orders:float

应用/模型/ order.rb

after_save :calculate_sum_of_total_orders
after_destroy :calculate_sum_of_total_orders

def calculate_sum_of_total_orders
  customer.update_column(:total_orders, orders.map(&:order_total_amount).sum)
end

它只会在您的customers表上运行一个QUERY,因为您的客户的总数已经存储,因此可以避免查询SUM中视图中每个客户的总数。

在您的控制器中

@customers = Customer.all

在您的视图中

只需汇总@ {1}}的@customers

total_orders

我希望它会有所帮助,如果我的答案不是最符合您需求的,那就很抱歉。

答案 1 :(得分:1)

在customers_controller.rb

@customer_details = []
@grand_total = 0
customers = Customer.includes(:order).find(:all)
customers.each do |customer|
  customer_total = customer.orders.map(&:order_total_amount).sum
  @customer_details << { :name => customer.name, :cus_total => customer_total }
  @grand_total += customer_total
end

查看index.rb

<% @customer_details.each do |c| %>
  <tr>
     <td id="name"><%= c[:name] %>
     <td id="cus_total"><%= c[:cus_total] %>
  </tr>
<% end %>
<tr>
  <td>Total</td>
  <td><%= @grand_total %></td>
</tr>