Như Kevin đã gợi ý, counter_cache là lựa chọn dễ dàng nhất, chắc chắn những gì tôi sẽ sử dụng.
class Author < ActiveRecord::Base
has_many :books, :counter_cache => true
end
class Book < ActiveRecord::Base
belongs_to :author
end
Và nếu bạn đang sử dụng Rails 2.3 và bạn sẽ như thế này là mặc định đặt hàng bạn có thể sử dụng phương pháp default_scope mới:
class Author < ActiveRecord::Base
has_many :books, :counter_cache => true
default_scope :order => "books_count DESC"
end
books_count là lĩnh vực mà thực hiện các hành vi truy cập bộ nhớ đệm, và có lẽ là một cách tốt hơn so với sử dụng nó trực tiếp trong phạm vi mặc định, nhưng nó mang lại cho bạn ý tưởng và sẽ hoàn thành công việc.
EDIT:
Để đối phó với những nhận xét hỏi nếu counter_cache sẽ làm việc nếu một ứng dụng đường ray không làm thay đổi dữ liệu, cũng có thể, nhưng không phải theo cách mặc định như Rails gia và decrements quầy ở tiết kiệm thời gian. Những gì bạn có thể làm là viết thực hiện của riêng bạn trong một cuộc gọi lại 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
Bây giờ bạn không có một counter_cache cài đặt, nhưng nếu bạn đặt tên cho trường trong books_count cơ sở dữ liệu theo quy ước counter_cache sau đó khi bạn nhìn lên:
@Author = Author.find(1)
puts @author.books.size
Nó sẽ vẫn sử dụng truy cập số được lưu trong bộ nhớ cache thay vì thực hiện tra cứu cơ sở dữ liệu. Tất nhiên điều này sẽ chỉ hoạt động khi ứng dụng đường ray cập nhật bảng, vì vậy nếu ứng dụng khác thực hiện điều gì đó thì số của bạn có thể không đồng bộ cho đến khi ứng dụng đường ray quay lại phải lưu lại. Cách duy nhất xung quanh điều này mà tôi có thể nghĩ là một công việc cron để đồng bộ số nếu ứng dụng đường ray của bạn không tra cứu mọi thứ thường xuyên đủ để làm cho nó không quan trọng.
làm bộ đệm truy cập hoạt động nếu ứng dụng không có đường ray cập nhật dữ liệu trong cơ sở dữ liệu trực tiếp (tức là xóa sách)? – dplante
Tôi cho rằng không, ít nhất là cho đến khi bạn lưu lại bản ghi từ ứng dụng te Rails. –