我是一个较新的开发者,我想知道我是否使用索引方法导致过多的查询。
我的所有权模型的索引方法如下所示:
def index
@ownerships = Ownership.all.select { |t| t.player_id == nil}
Rails.application.config.counter = (Ownership.all.count - Ownership.all.select{ |t| t.player_id == nil}.count) + 1
end
工作正常。目标是将计数器设置为等于未分配玩家的第一个所有权的ID。但我担心每次调用索引操作时都会导致3个单独的查询。是这样的吗?
我知道我可以找到第一张带有' nil'像这样的球员:
Ownership.all.select { |t| t.player_id == nil}.first(1)
是否有一种简单的方法可以将计数器设置为等于找到的记录的ID?
谢谢。
答案 0 :(得分:2)
在AR中使用Ruby效率很低,我建议将其作为最后的手段使用。
始终尝试进入数据库层。
以下AR查询
Ownership.find_by(player_id: nil)
触发单个SQL查询:
SELECT `ownerships`.*
FROM `ownerships`
WHERE `ownerships`.`player_id` = NULL
LIMIT 1
并完全满足您的需求。
请注意,如果找不到记录,则使用find_by
以下内容会导致NoMethodError
Ownership.find_by(player_id: nil).id
#=> NoMethodError: undefined method `id' for nil:NilClass
有关AR查询的详细信息,请查看finders docs。
答案 1 :(得分:2)
您正在选择所有现有的所有权,然后在Ruby中处理它们 - 效率非常低。如果你拥有10k所有权怎么办?还是100k?不仅对数据库的查询过于繁重,而且如果集合太大,Ruby也会耗尽内存。
您可能想要做的是使用SQL查找所有需要的记录。 在Rails中,您可以通过ActiveRecord查询为您生成SQL,如下所示:
@ownerships = Ownership.where(player_id: nil)
或
@ownership = Ownership.find_by(player_id: nil)
找到第一个匹配的。