2010-12-14 15 views
5

Ho un app rotaie con molti seguenti pezzi di codice:Qual è il modo giusto per fare i conteggi in Rails?

Our active community of <%= Account.find_all_by_admin(false).count %> 

La mia domanda è questo il modo giusto di fare i conteggi sulle viste? Sembra così "sporco" che ci sia un modo più peregrino di fare conti? Sto pensando forse agli scope nominati, ma voglio solo essere sicuro che questo tipo di cose non avrà un impatto maggiore sulle prestazioni.

Grazie,

risposta

6

Si consiglia di evitare l'accesso diretto al database nei miei modelli perché in questo modo si perde un po 'di flessibilità in termini di memorizzazione nella cache.

Provare a preparare tutti i dati necessari per il rendering nella propria azione e quindi utilizzare variabili di istanza significative come @number_of_accounts o @accounts.count.

Questo renderà il vostro punto di vista più pulito e più facile da eseguire il debug e anche un po 'di più DRY se rendere l'azione in diversi formati (HTML, JSON, ecc)

Quanto a come si fa a ottenere i numeri - doesn' t importa più di tanto, basta spostare lontano da metodi find_ * verso scoping e scrivere codice leggibile

+0

Questo era il tipo di risposta stavo cercando, perché so come farlo, volevo solo sapere il modo migliore per farlo. – Gotjosh

2

Un ambito di nome non dovrebbe avere un impatto sulle prestazioni

scope :not_admin, where(:admin => false) 

Poi si può avere Account.not_admin.count

A cura per il commento di DGM: Per controllare l'SQL generato in un console, confrontare Account.not_admin.to_sql con Account.find_all_by_admin(false).to_sql

+0

'Account.not_admin.count.to_sql' è un errore, almeno in Rails 3, dal momento che conta restituisce un Fixnum. – DGM

+0

Oops. Non posso testare qui, ma devi essere corretto. Tuttavia, Account.not_admin.to_sql e Account.find_all_by_admin (false) .to_sql dovrebbero essere equivalenti. –

1

In rails 3 una semplice chiamata per contare emette un semplice co Richiesta unt:

Contact.count 

viene risolto come:

SELECT COUNT(*) AS count_id FROM "contacts" 

un trovare tutti per nome di campo risolverà come:

Contact.find_all_by_country("Canada") 

SELECT "contacts".* FROM "contacts" WHERE ("contacts"."country" = 'Canada') 

lo consiglio indicizzare la colonna di amministrazione per le ricerche più veloci e questo può essere tradotto in un ambito con nome, ma questo di per sé solo predefinirà la query, non la ottimizzerà.

E 'importante notare che se si emette

Contact.find_all_by_country("Canada").count 

count è un metodo della classe array e in realtà non emettere un conteggio sulla base di dati:

Contact.find_all_by_country("Canada").count 

SELECT "contacts".* FROM "contacts" WHERE ("contacts"."country" = 'Canada') 
+0

date anche un'occhiata a questo articolo: http://www.railway.at/2010/03/09/named-scopes-are-dead/ –

+0

+1 per il Canada, eh ;-) – Ted

7

È don' t bisogno di un nome scope per eseguire un conteggio.

Account.where(:admin => false).count 

Ma gli ambiti denominati sono un modo eccellente per rendere il codice più riutilizzabile.

Gli ambiti con nome non hanno alcun impatto notevole sulle prestazioni dell'applicazione.

0

È possibile utilizzare seguente query invece di Account.where(:admin => false).count

Account.select(:id).where(:admin => false).count 

basta selezionare una colonna, invece di selezionare tutti. Esso genera la seguente interrogazione ed è più veloce rispetto alla precedente:

SELECT COUNT("accounts"."id") FROM "accounts" where admin = false 
Problemi correlati