A volte ActiveRecord non basta. Magari ti serve una query complessa con più join, oppure vuoi spremere ogni goccia di prestazioni dal tuo database. È lì che l'SQL raw torna utile.
Ecco tutto quello che devi sapere sull'esecuzione di SQL raw in Rails, dalle basi a come evitare gli errori più comuni.
Quando ti serve davvero l'SQL raw
Nella maggior parte dei casi ActiveRecord va benissimo. Ma ecco gli scenari reali in cui l'SQL raw ha senso:
- Aggregazioni complesse - Quando ti servono window function, CTE od operazioni GROUP BY complesse
- Query critiche per le prestazioni - Quando l'SQL generato da ActiveRecord è inefficiente
- Funzionalità specifiche del database - Usare gli operatori JSONB di PostgreSQL, la ricerca FULLTEXT di MySQL, ecc.
- Operazioni in blocco - Aggiornamenti massivi che sarebbero lenti con singole chiamate ActiveRecord
Passiamo alla pratica.
Un esempio reale: analytics degli utenti
Supponiamo che tu stia creando delle analytics sugli utenti e debba trovare quelli registrati negli ultimi 7 giorni, insieme al numero dei loro post. Ecco come si fa:
Tre modi per eseguire SQL raw
Rails ti offre diverse opzioni per eseguire SQL raw. Ecco le principali:
1. connection.execute - Per risultati raw
Usalo quando vuoi i risultati grezzi del database:
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 - Per oggetti del modello
Quando vuoi ottenere veri oggetti ActiveRecord:
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 con Arel - L'approccio ibrido
Nei casi semplici puoi comunque usare un po' di SQL raw con ActiveRecord:
User.where("created_at >= ?", 7.days.ago)
.pluck("name, email, DATE(created_at) as signup_date")
Non farti hackerare: prevenire la SQL injection
Questo è fondamentale: mai interpolare l'input dell'utente direttamente nelle stringhe SQL. Ecco il modo sbagliato:
# DON'T DO THIS - vulnerable to SQL injection
email = params[:email]
User.find_by_sql("SELECT * FROM users WHERE email = '#{email}'")
Usa invece le query parametrizzate:
# 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}")
I parametri vengono sottoposti automaticamente a escape e sono sicuri. Usali sempre.
Consigli sulle prestazioni
Spesso l'SQL raw riguarda le prestazioni, quindi ecco qualche consiglio da pro:
Usa Beekeeper Studio per analizzare le tue query: è perfetto per testare e ottimizzare l'SQL prima di inserirlo nella tua app Rails.
Aggiungi indici sulle colonne che usi per filtri o join:
# In a migration
add_index :users, :created_at
add_index :posts, [:user_id, :status]
Usa EXPLAIN per capire le prestazioni delle query:
ActiveRecord::Base.connection.execute("EXPLAIN ANALYZE #{your_sql}")
Valuta le viste del database per query complesse e riutilizzabili, invece di ripetere SQL raw ovunque.
In conclusione
L'SQL raw in Rails è come un coltello affilato: potente quando serve, ma va maneggiato con cura. Usalo per query complesse, ottimizzazione delle prestazioni e funzionalità specifiche del database che ActiveRecord non sa gestire.
Ricorda:
- Usa sempre query parametrizzate per prevenire la SQL injection
- Testa prima le tue query con uno strumento come Beekeeper Studio
- Non abbandonare del tutto ActiveRecord: usa l'SQL raw in modo strategico
Per approfondire
- Rails Guides: Active Record Query Interface
- Consigli sulle prestazioni di PostgreSQL
- Ottimizzazione delle query MySQL
- Prova Beekeeper Studio per lo sviluppo SQL: è il modo migliore per scrivere e testare query SQL
Hai domande sulla gestione dei database o sull'ottimizzazione SQL? Beekeeper Studio ti permette di esplorare facilmente i tuoi dati e perfezionare le query prima di metterle in produzione.
Beekeeper Studio è una GUI per database gratuita & open source
Il miglior strumento per query & editor SQL che abbia mai usato. Offre tutto ciò che mi serve per gestire il mio database. - ⭐⭐⭐⭐⭐ Mit
Beekeeper Studio è veloce, intuitivo e facile da usare. Beekeeper supporta tantissimi database e funziona alla grande su Windows, Mac e Linux.
Cosa dicono gli utenti di Beekeeper Studio
"Beekeeper Studio ha sostituito completamente il mio vecchio workflow SQL. È veloce, intuitivo e rende di nuovo piacevole lavorare con i database."
"Ho provato tante GUI per database, ma Beekeeper trova il perfetto equilibrio tra funzionalità e semplicità. Funziona e basta."