From e41320f6cb96fb04aa7f182387a65a3990a059c0 Mon Sep 17 00:00:00 2001 From: Nate Matykiewicz Date: Wed, 8 Nov 2023 15:50:14 -0600 Subject: [PATCH] Fix eager loading a Rails app with `performs` in an associated object ActiveJob::Performs was being included in an after_initialize hook, which was after the models were loaded, which means that an associated object that has a `performs` call in it had no `performs` method. This triggered the method_missing to run and find the `performs` method on the ActiveRecord model, use that, and then attempt to call my associated object name on the return value. Given this code: class AudioTrack::ListeningPlanDaySyncer < ActiveRecord::AssociatedObject performs :sync end `performs` didn't exist, so it'd call `AudioTrack.performs :sync`, which returns :sync_later. Then the method_missing code would attempt to run `:sync_later.listening_plan_day_syncer` and error. By moving this on_load hook out of `after_initialize`, I now have a `performs` method when eager loading. I think the only reason it was working before is because the models were being lazy loaded, so I didn't attempt to call `performs` until long after boot. --- lib/active_record/associated_object/railtie.rb | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/active_record/associated_object/railtie.rb b/lib/active_record/associated_object/railtie.rb index 8b715c3..5c04dc3 100644 --- a/lib/active_record/associated_object/railtie.rb +++ b/lib/active_record/associated_object/railtie.rb @@ -3,17 +3,17 @@ class ActiveRecord::AssociatedObject::Railtie < Rails::Railtie config.after_initialize do ActiveRecord::AssociatedObject.include Kredis::Attributes if defined?(Kredis) ActiveRecord::AssociatedObject.include GlobalID::Identification if defined?(GlobalID) - - ActiveSupport.on_load :active_job do - require "active_job/performs" - ActiveRecord::AssociatedObject.extend ActiveJob::Performs - rescue LoadError - # We haven't bundled active_job-performs, so we're continuing without it. - end end end initializer "object_association.setup" do + ActiveSupport.on_load :active_job do + require "active_job/performs" + ActiveRecord::AssociatedObject.extend ActiveJob::Performs + rescue LoadError + # We haven't bundled active_job-performs, so we're continuing without it. + end + ActiveSupport.on_load :active_record do require "active_record/associated_object/object_association" extend ActiveRecord::AssociatedObject::ObjectAssociation