Ruby on rails 如何使用ActiveRecord按作者的图书数量排序?

Ruby on rails 如何使用ActiveRecord按作者的图书数量排序?,ruby-on-rails,ruby,activerecord,Ruby On Rails,Ruby,Activerecord,假设我有图书模型和作者模型。我想列出所有按图书数量排序的作者。最好的方法是什么 我知道如何在SQL中实现这一点,无论是在何处。。在中使用嵌套选择或某些联接。但是我想知道的是如何在ActiveRecord中很好地实现这一点。我建议将书籍计数作为Author的另一个属性进行计数器缓存(Rails通过关联上的一个选项支持这一点)。这是目前为止最快的方法,Rails在确保计数同步方面做得非常好。摘自 正如凯文所建议的,计数器缓存是最简单的选择,我肯定会使用它 class Author < Acti

假设我有图书模型和作者模型。我想列出所有按图书数量排序的作者。最好的方法是什么


我知道如何在SQL中实现这一点,无论是在何处。。在中使用嵌套选择或某些联接。但是我想知道的是如何在ActiveRecord中很好地实现这一点。

我建议将书籍计数作为Author的另一个属性进行计数器缓存(Rails通过关联上的一个选项支持这一点)。这是目前为止最快的方法,Rails在确保计数同步方面做得非常好。

摘自


正如凯文所建议的,计数器缓存是最简单的选择,我肯定会使用它

class Author < ActiveRecord::Base
  has_many :books, :counter_cache => true
end

class Book < ActiveRecord::Base
  belongs_to :author
end
它仍将使用计数器缓存的编号,而不是执行数据库查找。当然,这只会在rails应用程序更新表时起作用,因此,如果另一个应用程序执行了某些操作,那么在rails应用程序返回并需要保存之前,您的号码可能会不同步。我能想到的唯一解决办法是,如果你的rails应用程序没有频繁地进行查找,使其变得无关紧要,那么使用cron任务来同步数字。

假设rails 3

@authors=Authors.include(:books).sort do |a,b| 
  a.books.size <=> b.books.size
end
@authors=authors.include(:books)。排序do | a,b |
a、 书的尺寸
结束
注意:这将返回一个记录数组,而不是ActiveRecord:Relation


注2:使用size,而不是count,因为count将执行对数据库的sql调用

谢谢你快速准确的回答。我用你的答案搜索了更多的信息,发现这也是非常有用的。我选择了railsninja的答案,因为它更全面,能更好地帮助路人。对。这基本上就是做一个SQL查询,让DBMS来做这项工作,这是最简单也是最好的方法。特别是,当一个查询可以满足您的需要时,您希望这样做以避免执行许多查询(每个作者可能有一个查询)。如果非rails应用程序直接更新数据库中的数据(即删除一本书),计数器缓存是否起作用?我想不会,至少在您再次从te rails应用程序保存记录之前不会。
class Author < ActiveRecord::Base
  has_many :books, :counter_cache => true

  default_scope :order => "books_count DESC"
end
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
@Author = Author.find(1)
puts @author.books.size
@authors=Authors.include(:books).sort do |a,b| 
  a.books.size <=> b.books.size
end