0

別の(請求書)の子であるモデル(LineItem)があります。LineItem内で、Invoiceの属性を参照するメソッドを委任します。このメソッドが実行されるときはいつでも、それは常にいくつかのSQLクエリを実行します...まるでそれが請求書をもう一度検索しているように

モデル「請求書」
-属性「created_at」を
含む-を含むdefault_scope includes(:line_items, :payments, :sales_person)

モデル"LineItem"
-含むdelegate :created_at, :to => :invoice, :prefix => true
-別のメソッドに含まれるもの:

@tax_rate ||= (category.to_sym == :books ? invoice_created_at.federal_tax_rate : invoice_created_at.tax_rate)

このメソッドで、(「ミニプロファイラー」gemを使用して)以下が生成されます。

SELECT `invoices`.* FROM `invoices`  WHERE `invoices`.`id` = 4 LIMIT 1
SELECT `line_items`.* FROM `line_items`  WHERE `line_items`.`invoice_id` IN (4)
SELECT `items`.* FROM `items`  WHERE `items`.`id` IN (31, 15)
SELECT `categories`.* FROM `categories`  WHERE `categories`.`id` IN (6, 1) ORDER BY name
SELECT `payments`.* FROM `payments`  WHERE `payments`.`invoice_id` IN (4)
SELECT `payment_types`.* FROM `payment_types`  WHERE `payment_types`.`id` IN (1) ORDER BY name
SELECT `sales_people`.* FROM `sales_people`  WHERE `sales_people`.`id` IN (1) ORDER BY name

これは、すべてのラインアイテムに対して行われます。これらのSELECTステートメントはすべて、invoice_created_at。*tax_rateメソッドが呼び出されるかなり前にすでに大量に発生しています...

SELECT `invoices`.* FROM `invoices`  WHERE (created_at between '2011-05-01 04:00:00' and '2013-02-06 04:59:59')
SELECT `line_items`.* FROM `line_items`  WHERE `line_items`.`invoice_id` IN (4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)

これらのSELECTクエリをすべて実行する必要がないようにするにはどうすればよいですか?

4

1 に答える 1

0

まず、使用をやめることができますdefault_scope includes。これは通常の場合には必要なく、おそらくあなたの場合にも必要ありません。

次に、さらに重要な:inverse_ofこととして、すでにメモリ内にあるオブジェクトの再読み込みを最小限に抑えるために、関連付けで属性を宣言する必要があります。

class Invoice < ActiveRecord::Base
  has_many :line_items, :inverse_of => :invoice
end

class LineItem < ActiveRecord::Base
  belongs_to :invoice, :inverse_of => :line_items
end
于 2013-02-06T03:36:14.790 に答える