Construindo Querys com ActiveRecord e Arel
Recentemente estava assistindo essa talk da RailsConf 2014 e achei interessante a forma apresentado por Cameron Dutro de como construir querys com ActiveRecord e Arel.
Ele mostra alguns exemplos de pesquisa utilizando strings em condições e joins e o porque isso pode ser ruim..
Vejamos essa query:
User.where("email ILIKE ?", '%teste%')
Por utilizarmos string para especificar as condições de busca, podemos acabar usando uma sintaxe exclusiva de um banco de dados..
No exemplo acima, faço uso de ILIKE
, que existe no PostgreSQL, mas não no MySQL. Essa é apenas uma das dores de cabeça que podemos ter ao usar strings pra esse tipo de coisa.
Como alternativa, Dutro supõe o uso do Arel para a construção de querys mais limpas e fáceis de manter. Veja como ficaria a busca acima com Arel:
User.where(User.arel_table[:email].matches("%teste%"))
O trecho acima, gera o mesmo SQL esperado que o primeiro:
SELECT "users".* FROM "users" WHERE ("users"."email" ILIKE '%teste%')
Brincando com Arel
Veja abaixo mais alguns exemplos de como podemos brincar com Arel em nossas querys seguido do correspondente SQL..
Eq
User.where(User.arel_table[:email].eq('teste@provedor.com'))
SELECT "users".* FROM "users" WHERE "users"."email" = 'teste@provedor.com'
Not Eq
User.where(User.arel_table[:email].not_eq('teste@provedor.com'))
SELECT "users".* FROM "users" WHERE ("users"."email" != 'teste@provedor.com')
In
User.where(User.arel_table[:email].in(['teste@provedor.com', 'outro@provedor.com']))
SELECT "users".* FROM "users" WHERE "users"."email" IN ('teste@provedor.com', 'outro@provedor.com')
Temos ainda outros operadores de comparação que podem ser vistos aqui.
Or e And
Achei legal também que podemos usar os operadores or
e and
.. Veja:
User.where(
User.arel_table[:email].eq(
'teste@provedor.com'
).or(
User.arel_table[:gender].eq('m').and(
User.arel_table[:name].eq('Teste')
)
)
)
SELECT "users".* FROM "users" WHERE (
(
"users"."email" = 'teste@provedor.com' OR
"users"."gender" = 'm' AND "users"."name" = 'Teste'
)
)
Arel Helpers Gem
Uma coisa chata é ter que ficar colocando .arel_table
toda vez depois do nome do model para acessar os atributos..
Não só para resolver esse problema, mas também outros e adicionar algumas features legais (como possibilitar a criação de query builders), o próprio Cameron Dutro criou uma gema chamada arel-helpers.
Fica a seu critério utilizá-la ou não.
Essa foi a dica de hoje. O que acharam?
Abraços.