我有一个模型(LineItem),它是另一个(Invoice)的子项。在LineItem中,我委托一个引用Invoice中属性的方法。无论何时运行此方法,它总是运行多个SQL查询...就像它重新搜索Invoice一样
模型“发票”
- 包含属性“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)
在这种方法中,生成以下内容(使用'迷你探查器'宝石):
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
它为每个订单项执行此操作。在调用invoice_created_at。* tax_rate方法之前,所有这些SELECT语句已经批量发生......
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查询?
答案 0 :(得分: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