Il metodo where
restituisce un oggetto ActiveRecord::Relation
e da solo questo oggetto non emette una query di database. È dove si utilizza questo oggetto che conta.
Nella console, probabilmente stai facendo questo:
@person = Person.where(name: "Jason")
E poi blammo emette una query di database e restituisce quello che sembra essere un array di tutti di nome Jason. Sì, Active Record!
Ma poi si fa qualcosa di simile:
@person = Person.where(name: "Jason").where(age: 26)
E poi che emette un'altra query, ma questo è per le persone che sono chiamati Jason che sono 26. Ma è solo l'emissione di una di query, quindi dove 'l'altra query va?
Come altri hanno suggerito, questo sta accadendo perché il metodo where
restituisce un oggetto proxy. In realtà non esegue una query e restituisce un set di dati a meno che non venga richiesto di farlo.
Quando si esegue nella console, verrà emessa la versione ispezionata del risultato di qualunque cosa si è eseguito. Se inserisci 1
nella console e premi Invio, riceverai 1
perché 1.inspect
è 1
. Magia! Lo stesso vale per "1"
. Una varietà di altri oggetti non ha un metodo inspect
definito e quindi Ruby ricade su quello Object
che restituisce qualcosa spettrale come <Object#23adbf42560>
.
Ogni singolo oggetto ActiveRecord::Relation
ha il metodo inspect
definito su di esso in modo che causi una query. Quando scrivi la query nella tua console, IRB chiamerà inspect
sul valore restituito da quella query e genererà qualcosa di quasi umano leggibile, come l'array che vedresti.
Se tu fossi solo il rilascio della presente in uno script standard di Ruby, allora nessuna query sarebbe eseguito fino a quando l'oggetto è stato ispezionato (via inspect
) o è stato iterato attraverso l'utilizzo di each
, o ha avuto il metodo to_a
chiamato su di esso.
Fino a una di quelle tre cose accadono, è possibile catena come molti where
dichiarazioni su come vi piace e poi quando si fare chiamata inspect
, to_a
o each
su di esso, allora sarà finalmente eseguire tale query.
E non lo fa presso l'ultimo metodo. Non ha modo di saperlo. Si consideri 'x = Person.where (..); @person = x.where (..) ', che dovrebbe essere identico. Lo fa qualche tempo dopo, quindi qual è il grilletto? ;-) –