2012-01-05 9 views
5

Ho due modelli ActiveRecord che hanno un'associazione HABTM.Come ottenere la tabella Arel di un'associazione di habtm?

Desidero scrivere un scope per ottenere i record orfani utilizzando Arel.

Il mio problema è che non sono riuscito a trovare un metodo per recuperare il arel_table dell'associazione. Poiché la relazione è HABTM, non esiste un modello per chiamare arel_table su.

Ho il seguente ora (che funziona), ma faccio una nuova tabella di Arel con il nome della tabella di join (recuperato utilizzando il metodo reflect_on_association).

scope :orphans, lambda { 
    teachers = arel_table 
    join_table = Arel::Table.new(reflect_on_association(:groups).options[:join_table]) 

    join_table_condition = join_table.project(join_table[:teacher_id]) 
    where(teachers[:id].not_in(join_table_condition)) 
} 

Questo produce il seguente SQL:

SELECT `teachers`.* 
FROM `teachers`  
WHERE (`teachers`.`id` NOT IN (SELECT `groups_teachers`.`teacher_id` 
           FROM `groups_teachers`)) 

Così, c'è un modo migliore per recuperare il arel_table invece di fare una nuova?

+0

Nota, penso che ci sia un modo più pulito per fare ciò, vedere la mia risposta qui sotto. – Andrew

risposta

2

Se si conosce il nome dell'associazione e pertanto se, che in questo caso sembra che si fa, si dovrebbe essere in grado di chiamare registrazione:

Arel::Table.new(:groups_teachers) 

Nel mio test che restituisce tavolo Arel di un'associazione di habtm. Grazie a this answer per avermelo fatto notare.

+0

Almeno ora (guardando ARel 3.0.2 e AR 3.2) puoi fare qualche brutta atletica come 'Groups.reflect_on_association (: teachers) .through_reflection.klass.arel_table', che dovrebbe darti un oggetto vincolato correttamente. – Nicos

+0

Esempio veloce se qualcuno è confuso! 'User.joins (: sports) .where (Arel :: Table.new (: sports_users) [: sport_id] .eq (SPORT_ID))' – Marrs

Problemi correlati