Come Kevin ha suggerito, counter_cache è l'opzione più semplice, sicuramente quello che avrei usato.
class Author < ActiveRecord::Base
has_many :books, :counter_cache => true
end
class Book < ActiveRecord::Base
belongs_to :author
end
E se si sta utilizzando Rails 2.3 e si vorrebbe che questa sia la Ordinamento predefinito è possibile utilizzare il nuovo metodo default_scope:
class Author < ActiveRecord::Base
has_many :books, :counter_cache => true
default_scope :order => "books_count DESC"
end
books_count è il campo che esegue il comportamento contatore di caching, e probabilmente c'è un modo migliore di utilizzarlo direttamente nell'oscilloscopio predefinito, ma ti dà l'idea e il lavoro sarà fatto.
EDIT:
In risposta al commento chiedendo se counter_cache funzionerà se un applicazione Rails non altera i dati, ben si può, ma non nel modo predefinito come Rails aumenti e le diminuzioni il contatore a risparmiare tempo. Quello che potresti fare è scrivere la tua implementazione in un callback after_save.
class Author < ActiveRecord::Base
has_many :books
after_save :update_counter_cache
private
def update_counter_cache
update_attribute(:books_count, self.books.length) unless self.books.length == self.books_count
end
end
Ora non si dispone di un counter_cache installato, ma se è il nome del campo nel books_count banca dati come da convenzione counter_cache poi quando si guarda:
@Author = Author.find(1)
puts @author.books.size
Sarà comunque possibile utilizzare la contatore in cache invece di eseguire una ricerca nel database. Ovviamente questo funzionerà solo quando l'app per i rails aggiorna la tabella, quindi se un'altra app fa qualcosa allora i tuoi numeri potrebbero non essere sincronizzati fino a quando l'applicazione rails non sarà ripristinata. L'unico modo per aggirare ciò che posso pensare è un cron job per sincronizzare i numeri se la tua app non esegue ricerche abbastanza spesso da renderlo non importa.
fa il contatore nella cache se un'applicazione non-rails aggiorna direttamente i dati nel database (ad esempio rimuove un libro)? – dplante
Suppongo di no, almeno finché non si salva di nuovo il record dall'app di Rails. –