Ruby on rails 无需第二次查询即可获得Rails记录计数

Ruby on rails 无需第二次查询即可获得Rails记录计数,ruby-on-rails,activerecord,Ruby On Rails,Activerecord,我有一个Rails ActiveRecord查询,可以查找名称为某个令牌的所有记录 records = Market.where("lower(name) = ?", name.downcase ); rec = records.first; count = records.count; 服务器显示对.first和.count的调用都命中了数据库 ←[1m←[35mCACHE (0.0ms)←[0m SELECT "markets".* FROM "markets" WHERE (lower

我有一个Rails ActiveRecord查询,可以查找名称为某个令牌的所有记录

records = Market.where("lower(name) = ?", name.downcase );
rec = records.first;
count = records.count;
服务器显示对
.first
.count
的调用都命中了数据库

←[1m←[35mCACHE (0.0ms)←[0m  SELECT "markets".* FROM "markets" WHERE (lower(nam
e) = 'my market') LIMIT 1

←[1m←[36mCACHE (0.0ms)←[0m  ←[1mSELECT COUNT(*) FROM "markets" WHERE (lower(na
me) = 'my market')←[0m
当它可以使用已经查询的结果时,为什么它要去数据库获取计数

我担心未来的表现。今天有1000张唱片。当该表包含800万行时,执行两个查询,一个查询数据,一个查询计数,这将非常昂贵


如何从集合而不是数据库中获取计数?

RactiveRecord使用惰性查询从数据库中获取数据。如果要简单地计算记录,则只能调用retrun数组的大小

records = Market.where("lower(name) = ?", name.downcase ).all
records.size

因此,
记录
是一个
活动关系
。你可能会认为这是一系列符合你的
where
标准的市场记录,但事实并非如此。每次您在该关系上引用类似于
first
count
的内容时,它都会执行查询以检索您所请求的内容

要将实际记录放入数组,只需将
.all
添加到关系中即可实际检索它们。比如:

records = Market.where("lower(name) = ?", name.downcase).all
count = records.count

适用于Rails 6.0.1和Ruby 2.6.5

您需要使用
to_a
将结果存储到数组中

records = Market.where("lower(name) = ?", name.downcase).to_a
这将创建SQL查询并将结果存储在数组
记录中

然后,当您调用
records.first
records.count
时,它将只返回数据或进行计算,而不会重新运行查询。这与
记录.size
记录.length
相同

另一个例子

我需要为我正在开发的博客做这件事。我试图运行一个查询来查找与一篇文章相关联的所有标记,我想计算有多少个标记。这导致了多次查询,直到我遇到
to_a
后缀

因此,我的SQL查询如下所示:

@tags = TagMap.where(post_id: @post).joins(:tag).select(:id, '"tags"."name"').to_a
这将在我的标记映射表中查找所有记录,这些记录的
post\u id
等于我正在查看的帖子的
id
。然后它连接到Tags表,并从Tags表中仅提取TagMap记录的
id
。然后将它们全部放入一个数组中。然后我可以运行
@tags.count
,它将返回该帖子的TagMap记录数,而无需再进行查询


我希望这能帮助任何使用Rails 6+

的人纠正错误。更多澄清->Rails 5的更新。将records.count更改为records.size仍然会导致额外的数据库查询。但将其更改为records.length没有,所以请尝试records.length。最后添加.all对查询结果没有任何影响。t.length也会导致Rails 5的DB查询(我使用Rails 5),.all->.to_a
.size
.length
在Rails 5.2中对我很有用,但是可能问题是如果计算初始对象的关系,您还需要
包括
activerecord关系。ie
User.first.customers.size
需要
User.includes(:customers)
Ah。我喜欢别人对我的NOOB自我评价:)