2014-04-25 31 views
3

我有一對ActiveRecord對象,它們具有belongs_to ... has_many關聯,has_many關聯是定製的。例如:ActiveRecord自定義has_many關聯對數據庫進行多次調用

首先AR對象:

class Car < Vehicle 
    has_many :wheels, class_name: "RoundObject", foreign_key: :vehicle_id, conditions: "working = 1" 

    validates_presence_of :wheels 
    ... 
end 

二AR對象:

class RoundObject < ActiveRecord::Base 
    belongs_to :vehicle 
    ... 
end 

請注意,上面沒有指示我的應用程序的功能,簡單地勾勒出我的兩個AR之間的關聯對象。

我遇到的問題是,當我重置緩存(並因此我的Rails應用程序重新緩存數據庫中的所有AR對象)時,當RoundObject對象得到重新緩存時,它對數據庫進行多次調用,每次調用與收集RoundObject相關聯的每個唯一vehicle_id。該SQL命令正在運行輸出到控制檯上,所以這是我的輸出看起來像:

RoundObject Load (2.0ms) SELECT `round_objects`.* FROM `round_objects` WHERE `round_objects`.`vehicle_id` = 28 AND (active = 1) 
    RoundObject Load (1.0ms) SELECT `round_objects`.* FROM `round_objects` WHERE `round_objects`.`vehicle_id` = 29 AND (active = 1) 
    RoundObject Load (2.0ms) SELECT `round_objects`.* FROM `round_objects` WHERE `round_objects`.`vehicle_id` = 30 AND (active = 1) 

我的應用程序使用內置has_many協會沒有任何修改其他幾個AR對象,我注意到,重置緩存時,它們只能訪問一次數據庫。例如:

Micropost Load (15.0ms) SELECT `microposts`.* FROM `microposts` INNER JOIN `posts` ON `posts`.`id` = `microposts`.`post_id` WHERE `microposts`.`active` = 1 AND `posts`.`active` = 1 

我的問題是,如何才能讓我的AR對象只打一次數據庫高速緩存復位,同時仍保持自定義has_many協會我需要什麼?我可以在被調用的SQL查詢上手動強制加入,這會有幫助嗎?

謝謝!

回答

3

在調用您的Vehicle對象以包含RoundObject時,您可以使用includes方法。
它會是這樣的:

Vehicle.where(conditions_for_getting_data).includes(:round_object) 
+2

謝謝您的回答。你能解釋爲什麼使用自定義'has_many'定義可能導致這種行爲發生? – Argus9

+2

@ Argus9這個問題並不是唯一的定製:has_many關聯。它被稱爲N + 1查詢問題,它可以影響任何:has_many關聯。您可以通過謹慎使用'includes'到「急切加載」來避免N + 1個查詢,它與單個查詢有很多關聯,而不是單個查詢。你應該在[Rails docs](http://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations)中閱讀'includes' –

相關問題