2013-04-03 88 views
7

我有幾個海量的SQL請求涉及到我的rails應用程序中的各種模型的連接。 單個請求可能涉及6到10個表。如何使用ARel加入子查詢?

爲了更快地運行請求,我想在連接中使用子查詢(這樣我可以在連接之前篩選這些表並將列減少到我需要的列)。我正在嘗試使用ARel來實現這一點。

我以爲我發現我的問題在那裏的解決方案:How to do joins on subqueries in AREL within Rails, 但事情一定已經改變,因爲我得到undefined method '[]' for Arel::SelectManager

有沒有人有任何想法如何實現這一點(不使用字符串)?

+0

你能顯示你正在嘗試的查詢嗎? – mguymon

+0

以便將其簡化到極限水平: SELECT A. * INNER JOIN(SELECT B.a_id FROM B WHERE Bc> 4)B ON A.id = B.a_id –

+0

您可以爲您嘗試的Ruby代碼查詢? – mguymon

回答

8

皮埃爾,我想到了一個更好的解決方案可能是由以下(從this gist靈感):

a = A.arel_table 
b = B.arel_table 

subquery = b.project(b[:a_id].as('A_id')).where{c > 4} 
subquery = subquery.as('intm_table') 
query = A.join(subquery).on(subquery[:A_id].eq(a[:id])) 

沒有特別的原因命名的別名「intm_table」,我只是認爲它不那麼令人困惑。

4

好吧,所以我的主要問題是,你不能加入一個Arel :: SelectManager ...但是你可以加入一個表別名。 因此產生在上述我的評論請求:

a = A.arel_table 
b = B.arel_table 

subquery = B.select(:a_id).where{c > 4} 
query = A.join(subquery.as('B')).on(b[:a_id].eq(a[:id]) 
query.to_sql # SELECT A.* INNER JOIN (SELECT B.a_id FROM B WHERE B.c > 4) B ON A.id = B.a_id