Find sul risultato di find. Possibile?

Ciao a tutti,

devo eseguire 2 find su un model, dove la seconda find genera un
sottoinsieme dei dati della prima, ad esempio:

a = User.find(:all, :conditions => "age > 18 ")
b = User.find(:all, :conditions => "age > 21 ")

vorrei evitare di rifare la query su tutti gli utenti, ma solo su quelli
di eta>18, l’ideale sarebbe eseguire
a.find(:all, :conditions => "age > 21 ")

ma a e’ un array e quindi nn prevede la find.
Cosa faccio:

  1. mi rassegno e faccio 2 query
  2. filtro l’array a con un ciclo

esiste un’altra immediata soluzione ?

grazie a tutti,
Ale

2010/2/24 Ale Ds [email protected]

a.find(:all, :conditions => "age > 21 ")

ma a e’ un array e quindi nn prevede la find.
Cosa faccio:

  1. mi rassegno e faccio 2 query
  2. filtro l’array a con un ciclo

esiste un’altra immediata soluzione ?

Potresti passare alla seconda query gli id dei record trovati nella
prima,
tipo

User.find(:all, :conditions => [“age > 21 && id IN (?)”,
primi.map(&:id)])

(e poi verificare se e’ davvero piu’ veloce che non rifare la query con
le
due condizioni sulla data, cosa di cui non sono sicuro!).

Ciao

Il 24 febbraio 2010 13.38, Luca De Marinis [email protected] ha
scritto:

2010/2/24 Ale Ds [email protected]

Potresti passare alla seconda query gli id dei record trovati nella prima,
tipo

User.find(:all, :conditions => [“age > 21 && id IN (?)”, primi.map(&:id)])

(e poi verificare se e’ davvero piu’ veloce che non rifare la query con le
due condizioni sulla data, cosa di cui non sono sicuro!).

Uhm… a occhio, per essere realmente più veloce, la prima query
dovrebbe restituire pochissimi risultati da una tabella immensa.

Un’idea un po’ azzardata (sintassi mysql, ma dovrebbe funzionare anche
con altri dbms):

a = User.find_by_sql [“SELECT *, (age > ?) as overage FROM users WHERE
age > ?”, 21, 18]
b = a.select {|x| x.overage == “1”}

pietro

hmm… rischio di essere pedante :slight_smile: ma:

2010/2/24 Ale Ds [email protected]:

a = User.find(:all, :conditions => "age > 18 ")
b = User.find(:all, :conditions => "age > 21 ")

forse, cercando una risposta, dovresti chiarirti alcune cose

  • ti servono entrambe le liste di utenti? e ti serve che siano distinte?
  • devi fare qualcosa di particolare con gli utenti della lista a che
    non sono nella lista b?

nota che: b e’ un sottinsieme proprio di a

quindi estraendo i dati con la prima query hai gia ottenuto anche
tutti gli elementi in b,
dunque non avresti bisogno di fare la seconda query, se comunque devi
processare tutti gli elementi in a.

qualcosa di simile a quello che cerchi lo potresti ottenere usando dei
named_scope, ma se lo facessi, viste le condizioni nei due casi,
otteresti una query tipo questa:

select * from users where age > 18 and age > 21

che e’ equivalente a:

select * from users where age > 21

Altrimenti se proprio hai bisogno dei due insiemi di utenti, potresti
fare deu query che estraggono i dati dei due sottoinsiemi disgiunti:

c = User.find(:all, :conditions => “age > 18 AND age <= 21”)
b = User.find(:all, :conditions => "age > 21 ")

N.B. c = a-b

ciao,
Luca