False "AVOID eager loading detected" on model association
jdufresne opened this issue · comments
Jon Dufresne commented
Given the following schema:
ActiveRecord::Schema[7.0].define(version: 2023_01_11_023828) do
create_table "m1_m2s", force: :cascade do |t|
t.integer "m1_id"
t.integer "m2_id"
end
create_table "m1s", force: :cascade do |t|
end
create_table "m2s", force: :cascade do |t|
end
create_table "m3s", force: :cascade do |t|
t.integer "m1_m2_id"
end
end
And the following model definitions:
class M1 < ApplicationRecord
has_many :m1_m2s
end
class M2 < ApplicationRecord
end
class M1M2 < ApplicationRecord
belongs_to :m1
belongs_to :m2
end
class M3 < ApplicationRecord
belongs_to :m1_m2
end
The following script results in a Bullet error:
Bullet.enable = true
Bullet.raise = true
Bullet.profile do
m1 = M1.create!
m2 = M2.create!
m1_m2 = M1M2.create!(m1:, m2:)
m3 = M3.new
m3.m1_m2 = m1.m1_m2s.find_by!(m2:)
puts M1M2.where(m2:).includes(:m1).index_by { |m1_m2| m1_m2.m1.id }
end
Actual
AVOID eager loading detected
M1M2 => [:m1]
Remove from your query: .includes([:m1])
Expected
No error.
I do not expect this error because the included m1 association is used every iteration the loop. As well, the cached m1.m1_m2s.find_by!(m2:)
is not used in the loop.
Introduction
This error is new to the project. I bisected the introduction of the error to:
commit c28200313471ade03dc2081f41b8ce3b84ba70b5
Author: Adam Zapaśnik <9281806+adamzapasnik@users.noreply.github.com>
Date: Fri Nov 25 09:27:27 2022 +0300
Fix n+1 false positives in AR7.0
lib/bullet/active_record70.rb | 7 +++++++
spec/integration/active_record/association_spec.rb | 13 +++++++++++++
2 files changed, 20 insertions(+)
Test project
I created a minimal test project that includes the models and script above at: