Ruby on rails 为什么有些Rails方法在我拥有集合时查询数据库

Ruby on rails 为什么有些Rails方法在我拥有集合时查询数据库,ruby-on-rails,Ruby On Rails,快速提问 所以我有一个集合,从数据库中检索,类似于: a = Invoice.all 然后我想得到该集合中所有金额的总和: a.sum(:amount) 它工作并返回正确的值,问题是,为什么Rails在.sum()部分进行第二次调用,而它已经可以访问整个集合,并且可以只查看集合中的记录 谢谢你的帮助 所以我有一个集合,从数据库中检索 a = Invoice.all 不,这不是一个“膨胀”的集合(它不包含任何对象)。它是一个关系/查询对象,描述什么样的对象满足这个查询 如果代码中只有这两行,

快速提问

所以我有一个集合,从数据库中检索,类似于:

a = Invoice.all
然后我想得到该集合中所有金额的总和:

a.sum(:amount)
它工作并返回正确的值,问题是,为什么Rails在
.sum()
部分进行第二次调用,而它已经可以访问整个集合,并且可以只查看集合中的记录

谢谢你的帮助

所以我有一个集合,从数据库中检索

a = Invoice.all
不,这不是一个“膨胀”的集合(它不包含任何对象)。它是一个关系/查询对象,描述什么样的对象满足这个查询

如果代码中只有这两行,那么只有一个查询,
sum
。如果您看到第二个查询,一定是有其他代码在发票上循环(或类似的东西)

所以我有一个集合,从数据库中检索

a = Invoice.all
不,这不是一个“膨胀”的集合(它不包含任何对象)。它是一个关系/查询对象,描述什么样的对象满足这个查询

如果代码中只有这两行,那么只有一个查询,
sum
。如果您看到第二个查询,一定是有其他代码在发票上循环(或类似的东西)


.all
实际上并不加载记录。相反,它为您提供了一个延迟加载的范围

ActiveRecord::Calculations
使用数据库获取合计,如总和。使用Rubys enumerable模块执行相同的操作可能会得到非常不同的结果,这就是为什么加载的集合不提供与签名匹配的
sum
方法的原因

if a.loaded?
  a.sum(&:amount) # use Enumerable#sum
else
  a.sum(:amount) # use ActiveRecord::Calculations#sum
end

.all
实际上并不加载记录。相反,它为您提供了一个延迟加载的范围

ActiveRecord::Calculations
使用数据库获取合计,如总和。使用Rubys enumerable模块执行相同的操作可能会得到非常不同的结果,这就是为什么加载的集合不提供与签名匹配的
sum
方法的原因

if a.loaded?
  a.sum(&:amount) # use Enumerable#sum
else
  a.sum(:amount) # use ActiveRecord::Calculations#sum
end

要记住的一点是

a = Invoice.all
#=> SELECT "invoices".* FROM "invoices"
鉴于

a.sum(:amount)
#=> SELECT SUM("invoices"."amount") FROM "invoices"
这两条语句都将触发ActiveRecord查询,因为rails就是这样工作的<代码>金额将使用
金额(“发票”“金额”)

如果不想启动ActiveRecord查询,可以使用
Array\sum

a.map(&:amount).sum
#=> 1234
# OR
a.to_a.sum(&:amount)
#=> 1234

要记住的一点是

a = Invoice.all
#=> SELECT "invoices".* FROM "invoices"
鉴于

a.sum(:amount)
#=> SELECT SUM("invoices"."amount") FROM "invoices"
这两条语句都将触发ActiveRecord查询,因为rails就是这样工作的<代码>金额将使用
金额(“发票”“金额”)

如果不想启动ActiveRecord查询,可以使用
Array\sum

a.map(&:amount).sum
#=> 1234
# OR
a.to_a.sum(&:amount)
#=> 1234

谢谢你的回复。在对a进行
操作之后,我还可以使用
.sum()
?@RomainGonçalvès:不可以。它现在是一个数组,而不是AR关系对象(因此,它不再具有AR关系api)。但是你可以使用数组/枚举方法求和。好的,谢谢@sergio tulentsev,我想这回答了我的问题。是否有一个库可以装饰从数据库中检索到的记录,并给我们一些糖来处理这些数据?一旦有可能,我会接受你的回答。@RomainGonçalvès:enumerable api的功能非常广泛。看看这些文档,你会惊讶于它的功能。一旦你加载了它们,只需使用
a.map(&:amount)。inject(0,:+)
谢谢你的回复。在对a进行
操作之后,我还可以使用
.sum()
?@RomainGonçalvès:不可以。它现在是一个数组,而不是AR关系对象(因此,它不再具有AR关系api)。但是你可以使用数组/枚举方法求和。好的,谢谢@sergio tulentsev,我想这回答了我的问题。是否有一个库可以装饰从数据库中检索到的记录,并给我们一些糖来处理这些数据?一旦有可能,我会接受你的回答。@RomainGonçalvès:enumerable api的功能非常广泛。看看这些文档,你会惊讶于它的功能。一旦你加载了它们,只需使用
a.map(&:amount).inject(0,:+)
您可以通过将块或方法名称传递给sum来避免映射。然后,我们必须首先将结果转换为数组,否则它将中断。您可以通过将块或方法名称传递给sum来避免映射。然后,我们必须首先将结果转换为数组,否则它将中断