Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: Ensure HABTM associations are not incorrectly labeled n+1 #581

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/bullet/detector/n_plus_one_query.rb
Expand Up @@ -35,6 +35,7 @@ def add_possible_objects(object_or_objects)

objects = Array(object_or_objects)
return if objects.map(&:bullet_primary_key_value).compact.empty?
return if objects.all? { |obj| obj.class.name =~ /^HABTM_/ }

Bullet.debug(
'Detector::NPlusOneQuery#add_possible_objects',
Expand Down
1 change: 1 addition & 0 deletions lib/bullet/stack_trace_filter.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
require "bundler"

module Bullet
module StackTraceFilter
Expand Down
9 changes: 9 additions & 0 deletions spec/integration/active_record/association_spec.rb
Expand Up @@ -401,6 +401,15 @@
end

describe Bullet::Detector::Association, 'has_and_belongs_to_many' do
context 'posts <=> deals' do
it 'should detect preload associations with join tables that have identifier' do
Post.includes(:deals).each { |post| post.deals.map(&:name) }
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations

expect(Bullet::Detector::Association).to be_completely_preloading_associations
end
end
context 'students <=> teachers' do
it 'should detect non preload associations' do
Student.all.each { |student| student.teachers.map(&:name) }
Expand Down
5 changes: 5 additions & 0 deletions spec/models/deal.rb
@@ -0,0 +1,5 @@
# frozen_string_literal: true

class Deal < ActiveRecord::Base
has_and_belongs_to_many :posts
end
1 change: 1 addition & 0 deletions spec/models/post.rb
Expand Up @@ -4,6 +4,7 @@ class Post < ActiveRecord::Base
belongs_to :category, inverse_of: :posts
belongs_to :writer
has_many :comments, inverse_of: :post
has_and_belongs_to_many :deals

validates :category, presence: true

Expand Down
12 changes: 12 additions & 0 deletions spec/support/sqlite_seed.rb
Expand Up @@ -21,6 +21,13 @@ def seed_db
post2 = category2.posts.create(name: 'second', writer: writer2)
post3 = category2.posts.create(name: 'third', writer: writer2)

deal1 = Deal.new(name: 'Deal 1')
deal1.posts << post1
deal1.posts << post2
deal2 = Deal.new(name: 'Deal 2')
post1.deals << deal1
post1.deals << deal2

comment1 = post1.comments.create(name: 'first', author: writer1)
comment2 = post1.comments.create(name: 'first2', author: writer1)
comment3 = post1.comments.create(name: 'first3', author: writer1)
Expand Down Expand Up @@ -156,6 +163,11 @@ def setup_db
t.column :hotel_id, :integer
end

create_table :deals_posts do |t|
t.column :deal_id, :integer
t.column :post_id, :integer
end

create_table :documents do |t|
t.string :name
t.string :type
Expand Down
1 change: 1 addition & 0 deletions test.sh
@@ -1,5 +1,6 @@
#bundle update rails && bundle exec rspec spec
#BUNDLE_GEMFILE=Gemfile.mongoid bundle update mongoid && BUNDLE_GEMFILE=Gemfile.mongoid bundle exec rspec spec
BUNDLE_GEMFILE=Gemfile.rails-6.1 bundle && BUNDLE_GEMFILE=Gemfile.rails-6.1 bundle exec rspec spec
BUNDLE_GEMFILE=Gemfile.rails-6.0 bundle && BUNDLE_GEMFILE=Gemfile.rails-6.0 bundle exec rspec spec
BUNDLE_GEMFILE=Gemfile.rails-5.2 bundle && BUNDLE_GEMFILE=Gemfile.rails-5.2 bundle exec rspec spec
BUNDLE_GEMFILE=Gemfile.rails-5.1 bundle && BUNDLE_GEMFILE=Gemfile.rails-5.1 bundle exec rspec spec
Expand Down