gpt4 book ai didi

ruby-on-rails - 在 Active Record (Rails) 中,如何从与每个父记录的 has_many 关系中选择列的总和?

转载 作者:行者123 更新时间:2023-11-29 12:32:53 25 4
gpt4 key购买 nike

考虑这个模型:

User:
id: int

Valuable:
id: int
user_id: int
value: int

用户有很多贵重元素。

现在是事情。我想使用 ActiveRecord 通过任何查询选择多个用户,之后我希望能够看到他们所有有值(value)的东西的总和,而不必进行 N+1 查询。

所以,我希望能够做到这一点:

# @var ids [Array] A bunch of User IDs.
User.where(id: ids).each do |u|
puts "User ##{u.id} has total value of #{u.total_value}
end

它应该执行 1(或最多 2)次查询,而不是实例化所有值。我尝试使用 select('*, SUM(valuables.value) as total_value).joins(valuables),但没有成功。我正在使用 PostgreSQL

如果可能的话,我希望它自动发生(例如使用 default_scope)并且我仍然希望能够使用 includes

更新:抱歉,我还不清楚这一点。 (实际上,我确实写了它)。我希望实例化所有有值(value)的东西。我想让 PostgreSQL 为我进行计算。

更新:我的意思是,我想依靠 PostgreSQL 的 SUM 方法来获得结果集中的总和。我认为我在使用 SELECTGROUP BY 方面所做的努力使这一点变得很清楚。我不希望 Valuables 表中的任何数据或记录对象成为结果的一部分,因为它消耗太多内存并且使用 Ruby 计算字段只会使用太多 CPU 并且花费太长时间。

最佳答案

在原始 SQL 中,你需要这样的东西:

SELECT users.*, SUM(valuable.value) AS values_sum
FROM users
LEFT OUTER JOIN valuables ON users.id = valuables.user_id
GROUP BY users.id

所以在 ActiveRecord 查询中翻译它看起来像这样:

User.select('users.*, SUM(valuables.value) AS total_value')
.joins('LEFT OUTER JOIN valuables ON users.id = valuables.user_id')

请注意,您实际上并未从 values 中选择任何列。

[10] pry(main)> @users = User.select('users.*, SUM(valuables.value) AS total_value').joins('LEFT OUTER JOIN valuables ON users.id = valuables.user_id')

User Load (1.4ms) SELECT users.*, SUM(valuables.value) as total_value FROM "users" LEFT OUTER JOIN valuables ON users.id = valuables.user_id
=> [#<User:0x007f96f7dff6e8
id: 8,
created_at: Fri, 05 Feb 2016 20:36:34 UTC +00:00,
updated_at: Fri, 05 Feb 2016 20:36:34 UTC +00:00>]
[11] pry(main)> @users.map(&:total_value)
=> [6]
[12] pry(main)>

然而,“default_scope”和“我仍然希望能够使用包含”的要求可能有点高,除非你想 manually load the associations .

关于ruby-on-rails - 在 Active Record (Rails) 中,如何从与每个父记录的 has_many 关系中选择列的总和?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35232482/

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