2012-09-17 24 views
0

考慮以下幾點:複製SQL語句的同時預先加載多個關聯(ActiveRecord的)

class Item < ActiveRecord::Base 
    has_many :order_items 
    has_many :orders, through: :order_items 

    attr_accessible :rent_price, :sale_price 
end 

class Order < ActiveRecord::Base 
    has_many :order_items, dependent: :destroy 

    def total 
    order_items.map(&:price).reduce(:+) 
    end 
end 

class OrderItem < ActiveRecord::Base 
    belongs_to :item 
    belongs_to :order 

    attr_accessible :type, :quantity 

    def item_price 
    item.send("#{type}_price") 
    end 

    def price 
    quantity * item_price 
    end 
end 

訂單號ORDER_ITEMS和訂單號總產量的SQL查詢:

 
irb(main):055:0> o = Order.last 
    Order Load (0.4ms) SELECT "orders".* FROM "orders" ORDER BY "orders"."id" DESC LIMIT 1 
=> #, balance: #, notes: nil, shipping_method: nil, shipping_details: nil, created_at: "2012-09-16 17:27:39", updated_at: "2012-09-16 21:09:56"> 

irb(main):056:0> oi = o.order_items.includes(item: :photos) 
    OrderItem Load (0.4ms) SELECT "order_items".* FROM "order_items" WHERE "order_items"."order_id" = 143 
    Item Load (0.2ms) SELECT "items".* FROM "items" WHERE "items"."id" IN (227) 
    Photo Load (0.1ms) SELECT "photos".* FROM "photos" WHERE "photos"."item_id" IN (227) 
=> [#, quantity: 1, size: 95, type: "rent", starts_on: "2012-09-17", ends_on: "2012-09-18", created_at: "2012-09-16 20:03:33", updated_at: "2012-09-16 21:09:56">] 

irb(main):057:0> o.order_items 
    OrderItem Load (0.4ms) SELECT "order_items".* FROM "order_items" WHERE "order_items"."order_id" = 143 
=> [#, quantity: 1, size: 95, type: "rent", starts_on: "2012-09-17", ends_on: "2012-09-18", created_at: "2012-09-16 20:03:33", updated_at: "2012-09-16 21:09:56">] 

irb(main):058:0> o.total 
    Item Load (0.4ms) SELECT "items".* FROM "items" WHERE "items"."id" = 227 LIMIT 1 
=> # 

應該怎樣做才能擺脫冗餘的SQL查詢?

回答

0

oi = o.order_items.includes(item: :photos)不改變o.order_items,添加包含它:它返回一個新的應用了額外選項的對象數組。

使用o = Order.includes(order_items: {item: photos}).last那麼o.order_items將不會執行任何查詢