# frozen_string_literal: truemoduleBulletmoduleActiveRecorddefself.enablerequire'active_record'::ActiveRecord::Base.class_evaldoclass<<selfalias_method:origin_find_by_sql,:find_by_sqldeffind_by_sql(sql,binds=[])result=origin_find_by_sql(sql,binds)ifBullet.start?ifresult.is_a?Arrayifresult.size>1Bullet::Detector::NPlusOneQuery.add_possible_objects(result)Bullet::Detector::CounterCache.add_possible_objects(result)elsifresult.size==1Bullet::Detector::NPlusOneQuery.add_impossible_object(result.first)Bullet::Detector::CounterCache.add_impossible_object(result.first)endelsifresult.is_a?::ActiveRecord::BaseBullet::Detector::NPlusOneQuery.add_impossible_object(result)Bullet::Detector::CounterCache.add_impossible_object(result)endendresultendendend::ActiveRecord::Relation.class_evaldoalias_method:origin_to_a,:to_a# if select a collection of objects, then these objects have possible to cause N+1 query.# if select only one object, then the only one object has impossible to cause N+1 query.defto_arecords=origin_to_aifBullet.start?ifrecords.size>1Bullet::Detector::NPlusOneQuery.add_possible_objects(records)Bullet::Detector::CounterCache.add_possible_objects(records)elsifrecords.size==1Bullet::Detector::NPlusOneQuery.add_impossible_object(records.first)Bullet::Detector::CounterCache.add_impossible_object(records.first)endendrecordsendend::ActiveRecord::Persistence.class_evaldodef_create_record_with_bullet(*args)_create_record_without_bullet(*args).tapdoBullet::Detector::NPlusOneQuery.update_inversed_object(self)Bullet::Detector::NPlusOneQuery.add_impossible_object(self)endendalias_method_chain:_create_record,:bulletend::ActiveRecord::Associations::Preloader.class_evaldo# include query for one to many associations.# keep this eager loadings.alias_method:origin_initialize,:initializedefinitialize(records,associations,preload_scope=nil)origin_initialize(records,associations,preload_scope)ifBullet.start?records=[records].flatten.compact.uniqreturnifrecords.empty?records.each{|record|Bullet::Detector::Association.add_object_associations(record,associations)}Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records,associations)endendend::ActiveRecord::FinderMethods.class_evaldo# add includes in scopealias_method:origin_find_with_associations,:find_with_associationsdeffind_with_associationsrecords=origin_find_with_associationsifBullet.start?associations=(eager_load_values+includes_values).uniqrecords.each{|record|Bullet::Detector::Association.add_object_associations(record,associations)}Bullet::Detector::UnusedEagerLoading.add_eager_loadings(records,associations)endrecordsendend::ActiveRecord::Associations::JoinDependency.class_evaldoalias_method:origin_instantiate,:instantiatealias_method:origin_construct_association,:construct_associationdefinstantiate(rows)@bullet_eager_loadings={}records=origin_instantiate(rows)ifBullet.start?@bullet_eager_loadings.eachdo|_klazz,eager_loadings_hash|objects=eager_loadings_hash.keysBullet::Detector::UnusedEagerLoading.add_eager_loadings(objects,eager_loadings_hash[objects.first].to_a)endendrecordsend# call join associationsdefconstruct_association(record,join,row)result=origin_construct_association(record,join,row)ifBullet.start?associations=[join.reflection.name]ifjoin.reflection.nested?associations<<join.reflection.through_reflection.nameendassociations.eachdo|association|Bullet::Detector::Association.add_object_associations(record,association)Bullet::Detector::NPlusOneQuery.call_association(record,association)@bullet_eager_loadings[record.class]||={}@bullet_eager_loadings[record.class][record]||=Set.new@bullet_eager_loadings[record.class][record]<<associationendendresultendend::ActiveRecord::Associations::CollectionAssociation.class_evaldo# call one to many associationsalias_method:origin_load_target,:load_targetdefload_targetBullet::Detector::NPlusOneQuery.call_association(@owner,@reflection.name)ifBullet.start?origin_load_targetendalias_method:origin_include?,:include?definclude?(object)Bullet::Detector::NPlusOneQuery.call_association(@owner,@reflection.name)ifBullet.start?origin_include?(object)endend::ActiveRecord::Associations::HasManyAssociation.class_evaldoalias_method:origin_empty?,:empty?defempty?ifBullet.start?&&!loaded?&&!has_cached_counter?(@reflection)Bullet::Detector::NPlusOneQuery.call_association(@owner,@reflection.name)endorigin_empty?endend::ActiveRecord::Associations::HasAndBelongsToManyAssociation.class_evaldoalias_method:origin_empty?,:empty?defempty?Bullet::Detector::NPlusOneQuery.call_association(@owner,@reflection.name)ifBullet.start?&&!loaded?origin_empty?endend::ActiveRecord::Associations::SingularAssociation.class_evaldo# call has_one and belongs_to associationsalias_method:origin_reader,:readerdefreader(force_reload=false)result=origin_reader(force_reload)ifBullet.start?unless@inversedBullet::Detector::NPlusOneQuery.call_association(@owner,@reflection.name)Bullet::Detector::NPlusOneQuery.add_possible_objects(result)endendresultendend::ActiveRecord::Associations::HasManyAssociation.class_evaldoalias_method:origin_has_cached_counter?,:has_cached_counter?defhas_cached_counter?(reflection=reflection())result=origin_has_cached_counter?(reflection)Bullet::Detector::CounterCache.add_counter_cache(owner,reflection.name)ifBullet.start?&&!resultresultendend::ActiveRecord::Associations::CollectionProxy.class_evaldodefcount(column_name=nil,options={})ifBullet.start?Bullet::Detector::CounterCache.add_counter_cache(proxy_association.owner,proxy_association.reflection.name)Bullet::Detector::NPlusOneQuery.call_association(proxy_association.owner,proxy_association.reflection.name)endsuper(column_name,options)endendendendend