1

一個Order有很多孩子ItemsItems有很多孩子Charges。在def display類型Controller方法及其相關視圖中,我期望顯示:1)order及其子items的所有屬性和2)amount屬性從Charges以各種用戶友好組合的總和。例如,當您只需要使用其中一個屬性時,是否優化內存以加載子對象?

<%= @order.id %> 
<%= @order.name %> 

<% @order.items.each do |item| %> 
    <%= item.id %> 
    <%= item.name %> 
<% end %> 

@total_item_charges 

# below 2 should sum into @total_item_charges above 
@total_item_type_a_charges 
@total_item_type_b_charges 

因爲我需要所有的items屬性後,我想我知道渴望載荷,但鑑於我才真正需要的charges(1至查詢)1個屬性,應該我渴望載荷爲好?

解決方法A

使用includes躍躍欲試負載孩子items以及孫子charges,以便需要的所有信息被加載一次,使用

# CONTROLLER 
@order = Order.includes(items: [:charges]).where(id: params[:order_id]).first 

# items/charges already loaded into memory 
@order.items.each do |i| 
    i.charges.each do |c| 
    if c.type == "type_a" 
     @total_item_type_a_charges += c.amount 
    else 
     @total_item_type_b_charges += c.amount 
    end 
    end 
end 

@total_item_charges = @total_item_type_a_charges + @total_item_type_b_charges 

B方法

仍渴望加載的孩子items,但不是grandchi ldren charges,而不是做where查詢需要

# CONTROLLER 
@order = Order.includes(:items).includes(:shipments).where(id: params[:order_id]).first 

@order.items.each do |i| 
    @total_item_type_a_charges += i.charges.where(type:"type_a").pluck(:amount).inject(:+) 
    @total_item_type_b_charges += i.charges.where(type:"type_b").pluck(:amount).inject(:+) 
end 

@total_item_charges = @total_item_type_a_charges + @total_item_type_b_charges 

在你的答案時......

  1. 共標誌,如果我使用includes完全錯誤的一切(一飲而盡,希望情況並非如此)
  2. 如果在內存使用和速度之間進行權衡(即一種方法更快,但使用更多內存,而另一種更慢但使用更少,請幫我標記,因爲這會有所幫助)
  3. 如果t他的回答是,要麼是罰款,要麼取決於細微的情況,我問的是因爲我想知道這裏是否有經驗法則
  4. 想知道如何在控制檯中測試這個嗎?我可以看到加載每個查詢的毫秒數,但不是內存使用率

回答

0

您將不得不考慮真實世界的情況,並且理想情況下需要進行一些性能測試。如果我要實現這一點,我會添加一個total_charge字段到Item,並保持更新,每當收費增加,更新或刪除,類似於belongs_to ... counter_cache: true

另一種可能是類似以下內容:

class Order < ActiveRecord::Base 
    has_many :items # as before 
    has_many :items_with_charge, :class_name: 'Item', 
      -> { joins(:charges).group('items.id').select('items.*, sum(charges.amount) as total_amount)') } 
    ... 
end 

現在,如果你這樣做:

order = Order.includes(:items_with_charge) 

每個項目應包括可佔總訪問使用5205​​

相關問題