gpt4 book ai didi

ruby-on-rails - ActiveRecord group by on a join

转载 作者:行者123 更新时间:2023-12-02 03:47:28 25 4
gpt4 key购买 nike

当我不得不加入另一张 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com