当我不得不加入另一张 table 时,我真的很努力地试图让一群人上类。当我不加入时,我可以让小组工作,但是当我想按另一张 table 上的列分组时,我开始遇到问题。

Tables:
Book
id, category_id

Category
id, name

ActiveRecord schema:

class Category < ActiveRecord::Base
  has_many :books
end

class Book < ActiveRecord::Base
  belongs_to :category
end

我正在尝试根据类别计数来分组。 IE。我想知道每个类别有多少本书。

我已经尝试了很多东西,这是最新的,
books = Book.joins(:category).where(:select => 'count(books.id), Category.name', :group => 'Category.name')

我想找回类似的东西
[{:name => fiction, :count => 12}, {:name => non-fiction, :count => 4}]

有任何想法吗?

提前致谢!

最佳答案

如果您只是在计算每个类别中的书籍数量,那么您从 has_many 关联中获得的关联方法可能就足够了(查看 Association Basics guide )。您可以使用以下方法获取属于特定类别的书籍数量

@category.books.size

如果您想构建您描述的数组,您可以使用以下内容自行构建:
array = Categories.all.map { |cat| { name: cat.name, count: cat.books.size } }

作为额外的一点,如果您可能经常查找某个类别中的图书数量,您可能还需要考虑使用计数器缓存,以便获取某个类别中的图书数量不需要额外访问数据库。为此,您需要在图书模型中进行以下更改:
# books.rb
belongs_to :category, counter_cache: true

并创建一个迁移来添加和初始化计数器缓存要使用的列:
class AddBooksCountToCategories < ActiveRecord::Migration
  def change
    add_column :categories, :books_count, :integer, default: 0, null: false

    Category.all.each do |cat|
      Category.reset_counters(cat.id, :books)
    end
  end
end

编辑 :经过一些实验,以下内容应该接近您想要的:
counts = Category.joins(:books).count(group: 'categories.name')

这将返回一个以类别名称作为键和计数作为值的散列。您可以使用 .map { |k, v| { name: k, count: v } } 然后将其完全设为您在问题中指定的格式。

不过,我会关注类似的事情——一旦你有足够多的书,加入可能会减慢速度。使用 counter_cache 始终是性能最好的,并且对于足够多的书籍,使用两个单独的查询预先加载也可能会给您更好的性能(这就是使用 includes 的预先加载从使用连接更改为 Rails 2.1 中的多个查询的原因) .

关于ruby-on-rails - ActiveRecord group by on a join,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16049594/

10-12 17:25
查看更多