Às vezes o ActiveRecord simplesmente não dá conta. Talvez você precise de uma query complexa com vários joins, ou queira extrair cada gota de performance do seu banco de dados. É aí que o SQL bruto se torna útil.
Aqui está tudo o que você precisa saber sobre executar SQL bruto no Rails - do básico até como evitar armadilhas comuns.
Quando você realmente precisa de SQL bruto
Na maioria das vezes, o ActiveRecord funciona muito bem. Mas estes são os cenários reais em que SQL bruto faz sentido:
- Agregações complexas - Quando você precisa de window functions, CTEs ou operações GROUP BY complexas
- Queries críticas para a performance - Quando o SQL gerado pelo ActiveRecord é ineficiente
- Recursos específicos do banco - Usar os operadores JSONB do PostgreSQL, a busca FULLTEXT do MySQL etc.
- Operações em massa - Atualizações em massa que seriam lentas com chamadas individuais do ActiveRecord
Vamos à parte prática.
Um exemplo real: analytics de usuários
Digamos que você esteja criando analytics de usuários e precise encontrar os usuários que se cadastraram nos últimos 7 dias, junto com a quantidade de posts de cada um. Veja como fica:
Três formas de executar SQL bruto
O Rails oferece várias opções para rodar SQL bruto. Estas são as principais:
1. connection.execute - Para resultados brutos
Use quando quiser os resultados brutos do banco de dados:
sql = <<~SQL
SELECT
u.id, u.name, u.email,
COUNT(p.id) as post_count
FROM users u
LEFT JOIN posts p ON p.user_id = u.id
WHERE u.created_at >= NOW() - INTERVAL '7 days'
GROUP BY u.id, u.name, u.email
ORDER BY post_count DESC
SQL
result = ActiveRecord::Base.connection.execute(sql)
result.each do |row|
puts "#{row['name']}: #{row['post_count']} posts"
end
2. find_by_sql - Para objetos de modelo
Quando você quer receber objetos ActiveRecord de verdade:
users = User.find_by_sql([
"SELECT * FROM users WHERE created_at >= ? AND status = ?",
7.days.ago, 'active'
])
users.each { |user| puts user.email }
3. pluck com Arel - A abordagem híbrida
Para casos simples, você ainda pode usar um pouco de SQL bruto com o ActiveRecord:
User.where("created_at >= ?", 7.days.ago)
.pluck("name, email, DATE(created_at) as signup_date")
Não seja hackeado: prevenção de SQL injection
Isto é crucial - nunca interpole entradas do usuário diretamente em strings SQL. Este é o jeito errado:
# DON'T DO THIS - vulnerable to SQL injection
email = params[:email]
User.find_by_sql("SELECT * FROM users WHERE email = '#{email}'")
Em vez disso, use queries parametrizadas:
# Safe approach with parameters
email = params[:email]
User.find_by_sql(["SELECT * FROM users WHERE email = ?", email])
# Or use connection.quote for raw execute
email = params[:email]
sanitized_email = ActiveRecord::Base.connection.quote(email)
result = ActiveRecord::Base.connection.execute("SELECT * FROM users WHERE email = #{sanitized_email}")
Os parâmetros são escapados automaticamente e são seguros. Use-os sempre.
Dicas de performance
SQL bruto costuma ter a ver com performance, então aqui vão algumas dicas de especialista:
Use o Beekeeper Studio para analisar suas queries - ele é perfeito para testar e otimizar SQL antes de colocá-lo no seu app Rails.
Adicione índices nas colunas que você usa em filtros ou joins:
# In a migration
add_index :users, :created_at
add_index :posts, [:user_id, :status]
Use EXPLAIN para entender a performance da query:
ActiveRecord::Base.connection.execute("EXPLAIN ANALYZE #{your_sql}")
Considere usar views do banco de dados para queries complexas e reutilizáveis, em vez de repetir SQL bruto por toda parte.
Conclusão
SQL bruto no Rails é como uma faca afiada - poderoso quando você precisa, mas deve ser manuseado com cuidado. Use-o para queries complexas, otimização de performance e recursos específicos do banco que o ActiveRecord não consegue lidar.
Lembre-se:
- Sempre use queries parametrizadas para evitar SQL injection
- Teste suas queries antes com uma ferramenta como o Beekeeper Studio
- Não abandone o ActiveRecord por completo - use SQL bruto de forma estratégica
Leitura complementar
- Rails Guides: Active Record Query Interface
- Dicas de performance do PostgreSQL
- Otimização de queries no MySQL
- Experimente o Beekeeper Studio para desenvolvimento SQL - é a melhor forma de escrever e testar queries SQL
Tem dúvidas sobre gerenciamento de bancos de dados ou otimização de SQL? O Beekeeper Studio facilita explorar seus dados e aperfeiçoar suas queries antes de colocá-las em produção.
Beekeeper Studio é um cliente de banco de dados gratuito e open source
A melhor ferramenta de consultas e edição de SQL que já usei. Tem tudo o que preciso para gerenciar meu banco de dados. - ⭐⭐⭐⭐⭐ Mit
O Beekeeper Studio é rápido, intuitivo e fácil de usar. Ele suporta vários bancos de dados e funciona muito bem no Windows, Mac e Linux.
O que os usuários dizem sobre o Beekeeper Studio
"O Beekeeper Studio substituiu completamente meu antigo fluxo de trabalho com SQL. É rápido, intuitivo e torna o trabalho com bancos de dados agradável de novo."
"Já testei muitas GUIs de banco de dados, mas o Beekeeper encontra o equilíbrio perfeito entre recursos e simplicidade. Simplesmente funciona."