diff --git a/lib/blueprinter-activerecord/preloader.rb b/lib/blueprinter-activerecord/preloader.rb index c4aea8f..67c8d7f 100644 --- a/lib/blueprinter-activerecord/preloader.rb +++ b/lib/blueprinter-activerecord/preloader.rb @@ -77,8 +77,13 @@ def self.preloads(blueprint, view_name, model=nil) # look for a matching association on the model ref = model ? model.reflections[assoc.name.to_s] : nil if (ref || model.nil?) && !assoc.blueprint.is_a?(Proc) - ref_model = ref && !(ref.belongs_to? && ref.polymorphic?) ? ref.klass : nil - acc[assoc.name] = preloads(assoc.blueprint, assoc.view, ref_model) + acc[assoc.name] = + if assoc.blueprint == blueprint and assoc.view == view_name + {} # halt on recursive blueprints + else + ref_model = ref && !(ref.belongs_to? && ref.polymorphic?) ? ref.klass : nil + preloads(assoc.blueprint, assoc.view, ref_model) + end end # look for a :preload option on the association diff --git a/test/preloads_test.rb b/test/preloads_test.rb index ca41286..9e99bcf 100644 --- a/test/preloads_test.rb +++ b/test/preloads_test.rb @@ -71,4 +71,13 @@ def test_preload_with_annotated_associations battery1: {refurb_plan: {}}, }, preloads) end + + def test_preload_with_recursive_association + blueprint = Class.new(Blueprinter::Base) do + association :children, blueprint: self + end + + preloads = BlueprinterActiveRecord::Preloader.preloads(blueprint, :default, Category) + assert_equal({children: {}}, preloads) + end end diff --git a/test/support/active_record_models.rb b/test/support/active_record_models.rb index 4c986eb..1422ee8 100644 --- a/test/support/active_record_models.rb +++ b/test/support/active_record_models.rb @@ -12,6 +12,8 @@ class Project < ActiveRecord::Base class Category < ActiveRecord::Base belongs_to :company + belongs_to :parent, class_name: "Category", optional: true + has_many :children, foreign_key: :parent_id, class_name: "Category", inverse_of: :parent end class Widget < ActiveRecord::Base diff --git a/test/support/active_record_schema.rb b/test/support/active_record_schema.rb index 718ebe4..ec7e700 100644 --- a/test/support/active_record_schema.rb +++ b/test/support/active_record_schema.rb @@ -15,6 +15,7 @@ def self.load! create_table :categories do |t| t.string :name, null: false + t.integer :parent_id t.text :description end