2013-07-29 79 views
1

我的應用程序是on Rails的2加載多個ActiveRecord的模型

我有2種型號,由has_and_belongs_to_many關係加入:MessageConversation。 所以我有3個表,messages,conversationsconversations_messages

是否可以在不使用:include選項的情況下加載同一個唯一查詢對象MessageConversation:include選項是不可能的,因爲我的查詢取決於一些外部參數。

實施例:

我可以從消息做一個查詢有每行

messages = Message.find(:all, 
    :select => "messages.*, conversations.*", 
    :conditions => some_conditions_depending_of_external_variables 
    :group => "messages.id" 
) 

所得表看起來像一對夫婦(MessageConversation):

`messages`.id | `messages`.field | `conversations`.id | `conversations`.field 
--------------+------------------+--------------------+------------------ 
1    | ...    | 10     | ... 
--------------+------------------+--------------------+------------------ 
2    | ...    | 15     | ... 
--------------+------------------+--------------------+------------------ 
3    | ...    | 10     | ... 
--------------+------------------+--------------------+------------------ 
4    | ...    | 20     | ... 

後此查詢,我的變量messages包含一組AR消息元素,但會話字段未作爲AR對話加載。

我希望能夠調用message.linked_conversation將同一行的對話作爲一個AR對象。

是否有任何方法可以在不重新加載對象的情況下執行此操作?

+0

不完全是你在找什麼,而是在兩個查詢中做到這一點,而不使用'包括'和重新加載的消息:http://stackoverflow.com/questions/12561688/how-to-eager-load-association-for-an-array-of-model-records – lulalala

回答

1

這是可能的。

您必須手動執行以下操作:include包含內部操作。這意味着與AR內部API集成,這不是你通常希望做的事情 - 它可以隨時在你升級Rails時破解。

這意味着你應該:

  1. 實例化會話手動對象從查詢結果
  2. 連接加載談話對象在消息中的關聯對象

Altough我建議拆分成兩個查詢,讓您將通過第二個查詢加載Conversation對象 - 這是基於您在第一個查詢中獲得的對話ID。在大多數情況下,性能會更好。之後,您只需將加載的對象附加到Message對象的關聯中即可。

爲了讓你的邏輯的一個粗略的例子:

# complex query to load messages and conversation ids 
messages = Message.find(...) 
# parse the loaded conversation ids out of resulting Message objects 
con_ids = messages.map {...} 
# load conversation objects through 2nd query 
conversations = Conversations.find(con_ids) 
# group conversations by message id 
con_by_message = conversations.group_by(&:message_id) 
# attach conversations into associations of Message objects 
messages.each {|m| 
    m.conversations.target = con_by_message[m.id] || [] 
} 

這是後話,對於Rails中has_many關聯的工作。我不能告訴你,如果設置association.target是足夠的habtm協會 - 你應該在源頭上挖掘...

+0

當然,這就是我在做什麼其實。但是我擔心大數據上的一些Rails處理(比如group_by)...這就是爲什麼我在尋找ActiveRecord的一些功能,它可以實現一個已經存在的對象。 '新'不能工作(這將是一個new_record); '創建'要麼(將創建一個其他objet)... – pierallard

+0

試着看Rails正在做什麼... https://github.com/rails/rails/blob/2-3-stable/activerecord/lib/ active_record/base.rb 如果你可以做一些#find_by_sql的操作: connection.select_all(sanitize_sql(sql),「#{name} Load」)。collect! {| record |實例化(記錄)} – jurglic