代码之家  ›  专栏  ›  技术社区  ›  Sijmen Mulder

如何用ActiveRecord按作者的图书数排序?

  •  6
  • Sijmen Mulder  · 技术社区  · 17 年前

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

    我知道如何在SQL中实现这一点,或者通过在哪里……使用嵌套的select或某些join。但我想知道的是如何用ActiveRecord很好地做到这一点。

    4 回复  |  直到 13 年前
        1
  •  9
  •   nitecoder    17 年前

    正如Kevin所建议的,计数器缓存是最简单的选择,绝对是我要使用的。

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

    如果您使用的是Rails 2.3,并且希望这是默认的顺序,那么您可以使用新的默认\u scope方法:

    class Author < ActiveRecord::Base
      has_many :books, :counter_cache => true
    
      default_scope :order => "books_count DESC"
    end
    

    books_count是执行计数器缓存行为的字段,可能有比直接在默认范围内使用它更好的方法,但它提供了一个想法,并将完成任务。

    编辑:

    在回应询问计数器缓存是否可以工作的评论时,如果一个非Rails应用程序改变了数据,它可以,但不是以默认的方式,随着Rails的增加和减少计数器在节省时间。您可以做的是在保存后回调中编写自己的实现。

    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
    

    它仍将使用计数器缓存的数字,而不是执行数据库查找。当然,这只在Rails应用程序更新表时有效,因此如果其他应用程序执行了某些操作,那么在Rails应用程序返回之前,您的号码可能不同步,必须保存。唯一能解决这个问题的方法是,如果你的Rails应用程序不经常查找数据而使其无关紧要,那么cron任务就是同步数据。

        2
  •  9
  •   daspianist    13 年前

    取自 http://www.ruby-forum.com/topic/164155

    Book.find(:all, :select => "author_id, count(id) as book_count", :group => "author_id", :order => "book_count")
    
        3
  •  7
  •   Kevin    17 年前

    我建议计数器缓存图书计数作为author的另一个属性(rails通过关联选项支持这一点)。这是迄今为止最快的方法,Rails非常擅长确保计数保持同步。

        4
  •  3
  •   Carlos Troncoso    14 年前

    假设轨道3

    @authors=Authors.include(:books).sort do |a,b| 
      a.books.size <=> b.books.size
    end
    

    注意:这将返回一个记录数组,而不是ActiveRecord:关系。

    注意2:使用SIZE而不是COUNT,因为COUNT将执行对数据库的SQL调用。

    推荐文章