在这种情况下,我遇到了N + 1问题:
Library
有许多Programs
。现在,我想让所有程序都位于某个国家/地区,因此我有一个代码:
country = "US"
programs = @libraries.includes(:programs).map do |library|
library.programs.where(country: country)
end
但是现在有N + 1个问题:
Program Load (0.8ms) SELECT "programs".* FROM "programs" WHERE "programs"."library_id" = $1 AND "programs"."country" = $2 [["library_id", 15], ["country", "US"]]
Program Load (0.4ms) SELECT "programs".* FROM "programs" WHERE "programs"."library_id" = $1 AND "programs"."country" = $2 [["library_id", 73], ["country", "US"]]
Program Load (0.5ms) SELECT "programs".* FROM "programs" WHERE "programs"."library_id" = $1 AND "programs"."country" = $2 [["library_id", 27], ["country", "US"]]
Program Load (0.3ms) SELECT "programs".* FROM "programs" WHERE "programs"."library_id" = $1 AND "programs"."country" = $2 [["library_id", 177], ["country", "US"]]
Program Load (0.3ms) SELECT "programs".* FROM "programs" WHERE "programs"."library_id" = $1 AND "programs"."country" = $2 [["library_id", 38], ["country", "US"]]
Program Load (0.4ms) SELECT "programs".* FROM "programs" WHERE "programs"."library_id" = $1 AND "programs"."country" = $2 [["library_id", 51], ["country", "US"]]
Program Load (0.6ms) SELECT "programs".* FROM "programs" WHERE "programs"."library_id" = $1 AND "programs"."country" = $2 [["library_id", 18], ["country", "US"]]
Program Load (0.3ms) SELECT "programs".* FROM "programs" WHERE "programs"."library_id" = $1 AND "programs"."country" = $2 [["library_id", 20], ["country", "US"]]
Program Load (0.5ms) SELECT "programs".* FROM "programs" WHERE "programs"."library_id" = $1 AND "programs"."country" = $2 [["library_id", 42], ["country", "US"]]
Program Load (0.5ms) SELECT "programs".* FROM "programs" WHERE "programs"."library_id" = $1 AND "programs"."country" = $2 [["library_id", 39], ["country", "US"]]
更新:
我的目的不是仅仅过滤programs
,而是要使用它。例如:
programs = @libraries.includes(:programs).each do |library|
if library.programs.where(country: country).size < 5
puts "US programs are less than 5 so you can still add"
end
end
有人知道如何解决N + 1问题吗?
答案 0 :(得分:1)
您可以 将where
查询链接到includes
,如下所示
programs = @libraries.includes(:programs).where(programs: {country: country})
应该可以解决 N + 1 问题。
请参见specifying-conditions-on-eager-loaded-associations
更新#1:
您可以这样简单地完成
programs = @libraries.includes(:programs).where(programs: {country: country}).size < 5 #returns true or false
if programs #true
puts "US programs are less than 5 so you can still add"
else #false
#your code
end
更新#2:
这应该做
programs_size = @libraries.includes(:programs).where(programs: {country: country}).map { |library| library.programs.size }
仅执行一个查询,并返回与条件匹配的每个library.programs
的大小作为数组,如下所示< / p>
=> [5, 4, 7, 4, 6, 2, 1]
现在您可以遍历programs_size
数组并执行逻辑
programs_size.each do |ps|
if ps < 5 #true
puts "US programs are less than 5 so you can still add"
else #false
#your code
end
end