Arel é uma biblioteca construída em trilhos, que simplifica as consultas e se adapta a diferentes RDBMS.
Tenho trabalhado recentemente com consultas que requerem alguma otimização sem perder os recursos do ActiveRecord.
A seleção de uma soma, por exemplo, normalmente é feita com:
MyModel.sum(:field)
Mas e se você quiser adicionar um modelo relacionado ao qual deseja participar e obter uma soma de um de seus campos?
Uma opção é escrever o seguinte:
MyModel.select( 'my_model.*, sum( my_other_model.field2 )').group( 'my_model.*')
Usando Arel, podemos simplificar e torná-lo portátil também!
MyModel.select( [ arel_table[ Arel.star ], 'sum(my_other_model.field2 ]) as field2_total').group( 'my_model.id' )
dependendo do seu RDBMS, você obterá algo no caminho de:
SELECT `my_model`.*, sum( my_other_model.field2 ) as field2_total FROM `my_model` INNER JOIN `my_other_model` ON `my_model`.`id` = `my_other_model`.`id` GROUP BY `my_model`.`id`
Também podemos adicionar arel_table[primary_key]
à cláusula de grupo:
MyModel.select([ arel_table[ Arel.star ], 'sum(my_other_model.field2' ]) as field2_total').group( arel_table[primary_key] )
E devemos obter a mesma saída.
SELECT `my_model`.*, sum( my_other_model.field2 ) as field2_total FROM `my_model` INNER JOIN `my_other_model` ON `my_model`.`id` = `my_other_model`.`id` GROUP BY `my_model`.`id`