# Ottmizzazione delle ricerche nel DB

**URL:** <https://www.ruby-forum.com/t/ottmizzazione-delle-ricerche-nel-db/169826>\
**Category:** IT\
**Created:** [June 9, 2009, 10:44am UTC](https://www.ruby-forum.com/t/ottmizzazione-delle-ricerche-nel-db/169826 "2009-06-09T10:44:56Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![softwarewin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/5f9b8f/32.png) [@softwarewin](https://www.ruby-forum.com/u/softwarewin)\
**Post date:** [June 9, 2009, 10:44am UTC](https://www.ruby-forum.com/t/ottmizzazione-delle-ricerche-nel-db/169826/1 "2009-06-09T10:44:56Z")

</div>

Salve ragazzi,  
ho costruito un aplicazione dove sono presenti 3 tabelle:  
1 - contiene le leggi  
2 - contiene gli utenti  
3 - contiene i voti degli utenti sugli articoli

la terza tabella Ã¨ di collegamento alle prime due dato che ogni rigo  
(ID) contiene l’id della legge, l’id dell’utente e il voto.

Nella home vengono riportati tutti gli articoli e per ogni articolo  
vengono raccolti i numeri di voti positivi e negativi.

I modelli definiscono le varie associazioni:

laws-\> has\_many:votes

users -\> has\_many:laws

votes -\>  
belongs\_to :user  
belongs\_to :laws

nel controller Law definisco la vista index:  
def index  
@votes=Vote  
@laws=Law.find(:all,:conditions=\>‘public’,:order=\>‘updated desc’)  
end

Come potete notare @votes non fa alcuna ricerca specifica ma aggancia  
l’intera tabella.

## Questo mi Ã¨ necessario perchÃ© poi nel ciclo for, della vista index, che elenca tutte le leggi per ogni legge devo contare all’interno di @votes il numero di voti:

## \<%for law in @laws-%\> \<%=law.title-%\> … \<%=@votes.count(:all,:conditions=\>“law\_id=#{law.id} and yes”)-%\> \<%end-%\>

Quindi per ogni articolo visualizzato devo fare un’interrogazione nel DB  
o meglio nell’array @votes.

Veniamo alla domanda:

esiste un modo piÃ¹ efficace e meno impegnativo per la CPU?

mi sapete dare qualche suggerimento per migliorare il codice?

Grazie mille

Luigi

---

<div class="post-metadata">

**Author:** ![softwarewin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/5f9b8f/32.png) [@softwarewin](https://www.ruby-forum.com/u/softwarewin)\
**Post date:** [June 9, 2009, 11:29am UTC](https://www.ruby-forum.com/t/ottmizzazione-delle-ricerche-nel-db/169826/2 "2009-06-09T11:29:37Z")

</div>

Luigi M. wrote:

> @votes=Vote  
> @laws=Law.find(:all,:conditions=\>‘public’,:order=\>‘updated desc’)  
> end
> 
> Come potete notare @votes non fa alcuna ricerca specifica ma aggancia  
> l’intera tabella.

la classe Vote Ã¨ dispobilile anche nella vista, senza bisogno di  
referenziarla con una variabile di istanza. Ti ricordo pero’ che nella  
vista la logica non ci dovrebbe stare, il suo posto Ã¨ il controller o  
alla peggio l’helper.

> \<%for law in @laws-%\>  
> \<%=law.title-%\>  
> …  
> \<%=@votes.count(:all,:conditions=\>“law\_id=#{law.id} and yes”)-%\>

Che significa quel and yes?  
Comunque, visto che hai dichiarato le associazioni necessarie puoi usare  
direttamente law.votes.count invece di quella robaccia 🙂

Nel controller puoi usare  
@laws=Law.find(:all, :conditions=\>‘public’, :order=\>‘updated desc’,  
:include =\> :votes)  
per tirarti su anche tutti i voti associati alle leggi, ti risparmi un  
po’ di query. Quel :conditions =\> ‘public’ e’ inquietante.

Se vuoi ottimizzare ulteriormente puoi usare una counter cache, trovi  
tutorial in rete o cercati un libro recente su rails, penso che ti  
aiuterebbe molto.

---

<div class="post-metadata">

**Author:** ![softwarewin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/5f9b8f/32.png) [@softwarewin](https://www.ruby-forum.com/u/softwarewin)\
**Post date:** [June 10, 2009, 3:22pm UTC](https://www.ruby-forum.com/t/ottmizzazione-delle-ricerche-nel-db/169826/3 "2009-06-10T15:22:27Z")

</div>

Grazie mille,  
perdonatemi ma non ho ancora avuto il tempo di provare.

‘and yes’ serve a contare i voti positivi, sarebbe yes=true.

Ma perchÃ© :conditions=\>‘public’ Ã¨ inquitante???

Grazie

Luigi

---

<div class="post-metadata">

**Author:** ![softwarewin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/5f9b8f/32.png) [@softwarewin](https://www.ruby-forum.com/u/softwarewin)\
**Post date:** [June 10, 2009, 5:10pm UTC](https://www.ruby-forum.com/t/ottmizzazione-delle-ricerche-nel-db/169826/4 "2009-06-10T17:10:28Z")

</div>

Ok,  
law.votes.count(:conditions=\>‘yes’) l’ho risolto.

Continuo a non capire il:

PerchÃ© :conditions=\>‘public’ Ã¨ inquitante???

Luigi

---

<div class="post-metadata">

**Author:** ![softwarewin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/5f9b8f/32.png) [@softwarewin](https://www.ruby-forum.com/u/softwarewin)\
**Post date:** [June 10, 2009, 5:04pm UTC](https://www.ruby-forum.com/t/ottmizzazione-delle-ricerche-nel-db/169826/5 "2009-06-10T17:04:17Z")

</div>

> Andrea L. wrote:  
> Che significa quel and yes?  
> Comunque, visto che hai dichiarato le associazioni necessarie puoi usare  
> direttamente law.votes.count invece di quella robaccia 🙂

Ciao Andrea,  
law.votes.count non funziona correttamente dato che mi calcola tutti i  
voti sia i positivi che i negativi.

Questo perchÃ© nella tabella votes esiste la voce yes (tinyint (1)).

E’ per questo che nel codice che avevo scritto c’Ã¨ ‘… and yes’.

Come faccio? (mi piace tanto quel law.votes.count)

PerchÃ© :conditions=\>‘public’ Ã¨ inquitante???

Grazie mille

Luigi

---

<div class="post-metadata">

**Author:** ![softwarewin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/5f9b8f/32.png) [@softwarewin](https://www.ruby-forum.com/u/softwarewin)\
**Post date:** [June 10, 2009, 6:06pm UTC](https://www.ruby-forum.com/t/ottmizzazione-delle-ricerche-nel-db/169826/6 "2009-06-10T18:06:15Z")

</div>

Un’altra domanda:  
ma un comando di questo tipo

law.votes.count

implica una ricerca nel DB cosÃ¬ come il comando

@votes.count(:all,:conditions=\>“law\_id=#{law.id} and yes”)

?

cioÃ¨ dal punto di vista dello sfruttamento del DB Ã¨ lo stesso?

e inoltre c’Ã¨ differenza, sempre dal punto di vista dello sfruttamento  
del DB, se la ricerca viene eseguita nel controller oppure nella vista?

Per Andrea L.:

PerchÃ© :conditions=\>‘public’ Ã¨ inquitante???

Grazie sempre

Luigi

---

<div class="post-metadata">

**Author:** ![softwarewin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/5f9b8f/32.png) [@softwarewin](https://www.ruby-forum.com/u/softwarewin)\
**Post date:** [June 11, 2009, 12:45am UTC](https://www.ruby-forum.com/t/ottmizzazione-delle-ricerche-nel-db/169826/7 "2009-06-11T00:45:11Z")

</div>

Luigi M. wrote:

> Un’altra domanda:  
> ma un comando di questo tipo
> 
> law.votes.count
> 
> implica una ricerca nel DB cosÃ¬ come il comando
> 
> @votes.count(:all,:conditions=\>“law\_id=#{law.id} and yes”)
> 
> ?

Dipende. Se hai giÃ raccolto i voti associati a quella legge no. Per  
toglierti questi dubbi Ã¨ sufficiente guardare il file development.log  
mentre smanetti con l’applicazione nel browser, o ancora meglio nella  
console in casi come questo. Da teminale se sei su un sistema unix-like:  
tail -f log/development.log

> e inoltre c’Ã¨ differenza, sempre dal punto di vista dello sfruttamento  
> del DB, se la ricerca viene eseguita nel controller oppure nella vista?

No, ma certe cose nelle viste non ci dovrebbero essere.

> Per Andrea L.:
> 
> PerchÃ© :conditions=\>‘public’ Ã¨ inquitante???

Perche’ non Ã¨ il massimo della chiarezza, come lo yes del resto…  
pessimo nome per un campo, non trovi? Sai, finche’ il codice lo legge  
solo chi lo scrive va bene qualsiasi schifezza basta che funzioni(si fa  
per dire, quando dopo 6 mesi rileggi il tuo stesso codice ti voglio  
proprio vedere se capisci al volo cosa significa il campo yes), ma se lo  
devono leggere anche gli altri… beh meglio che sia chiaro.  
Io espliciterei la condizione con

@laws = Law.all(:conditions =\> {:public =\> true})

o ancora meglio metterei un named\_scope nel modello:

class Law \< ActiveRecord::Base  
named\_scope :public, :conditions =\> {:public =\> true}

# …

end

cosÃ¬ quando scrivi Law.public ti trova tutte le leggi pubbliche…  
potresti fare la stessa cosa coi voti, qualcosa del tipo:

class Votes \< ActiveRecord…  
named\_scope :positive, :conditions =\> {:yes =\> true}  
#…  
end
