Questo episodio affronta le condizioni del metodo find
. Di sotto sono riportate alcune linee dalla script/console
, che mostrano l’ SQL che è prodotto da questi comandi.
Task.find(:all, :conditions => ["completed = ? AND priority = ?", false, 2])
SELECT * FROM "tasks" WHERE (completed = 'f' AND priority = 2)
Trova tutti i task incompleti che hanno prorità pari a 2.
L’esempio di sopra funziona, ma come faremmo a recuperare tutti i Tasks
che hanno una priority
che vale nil
?
Task.find(:all, :conditions => ["completed = ? AND priority = ?", false, nil])
SELECT * FROM "tasks" WHERE (completed = 'f' AND priority = NULL)
La ricerca per valori null produce SQL scorretto.
L’SQL prodotto sopra non è corretto. Per recuperare valori null, la corretta sintassi sarebbe infatti priority IS NULL
, non priority = NULL
. Analogamente, se volessimo recuperare i record passando più di un valore per il campo priority, usando un array o un range, dovremmo cambiare lo statement di find per usare correttamente IN
al posto di =
, e mettere le parentesi a contorno del secondo punto di domanda, al fine di garantire che l’SQL prodotto sia sintatticamente corretto.
Task.find(:all, :conditions => ["completed = ? AND priority IN (?)", false, [1,3]])
SELECT * FROM "tasks" WHERE (completed = 'f' AND priority IN (1,3))
A partire da Rails 1.2, c’è un modo miglior per passare le condizioni: mediante un hash. Usare un hash di condizioni garantisce che Rails adotti le condizioni appropriate quando esegue le query sul database.
Task.find(:all, :conditions => { :completed => false, :priority => [1,3] }
SELECT * FROM "tasks" WHERE (completed = 'f' AND priority IN (1,3)
Uso di un hash di condizioni con un parametro array.
Task.find(:all, :conditions => {:completed => false, :priority => 2..4})
SELECT * FROM "tasks" WHERE ("tasks"."priority" BETWEEN 2 AND 4 AND "tasks"."completed" = 'f')
Se si passa un range, questo viene tradotto con la clausola BETWEEN
nell’SQL.
Utilizzo con find dinamiche
Nell’episodio 2 abbiamo usato metodi find_by
dinamici. Anche questi possono accettare valori nil, array o range come argomenti.
Task.find_by_priority(1..5)
SELECT * FROM "tasks" WHERE ("tasks"."priority" BETWEEN 1 AND 5) LIMIT 1
L’utilizzo di hash nelle condizioni di find assicura che Rails generi l’SQL corretto al passaggio di un qualsiasi tipo di parametro alla find.