2013-04-03 9 views
7

Ho una massiccia richiesta SQL che coinvolge join su vari modelli nella mia applicazione rails. Una singola richiesta può coinvolgere da 6 a 10 tabelle.Come partecipare alle sottoquery usando ARel?

Per eseguire la richiesta più rapidamente, desidero utilizzare le sottocarelle nei join (in questo modo posso filtrare queste tabelle prima del join e ridurre le colonne a quelle necessarie). Sto cercando di raggiungere questo obiettivo usando ARel.

Pensavo di aver trovato la soluzione al mio problema lì: How to do joins on subqueries in AREL within Rails, ma le cose devono essere cambiate perché ottengo undefined method '[]' for Arel::SelectManager.

Qualcuno ha idea di come ottenere ciò (senza utilizzare le stringhe)?

+0

Puoi mostrare la query che stai tentando? – mguymon

+0

Bene per semplificarlo al livello estremo: SELEZIONA A. * INNER JOIN (SELEZIONA B.a_id FROM B WHERE Bc> 4) B ON A.id = B.a_id –

+0

Puoi il codice Ruby che stai provando per interrogare? – mguymon

risposta

8

Pierre, ho pensato che una soluzione migliore potrebbe essere la seguente (ispirazione da 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])) 

Nessun motivo particolare per la denominazione l'alias come "intm_table", ho pensato che sarebbe stato meno confuso.

4

OK, quindi il mio problema principale era che non è possibile unirsi a un Arel :: SelectManager ... MA è possibile partecipare a un alias di tabella. Quindi, per generare la richiesta nel mio commento sopra:

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 
Problemi correlati