diff --git a/mapper/lib/rom/struct_compiler.rb b/mapper/lib/rom/struct_compiler.rb index 7dfa554f4..71a128920 100644 --- a/mapper/lib/rom/struct_compiler.rb +++ b/mapper/lib/rom/struct_compiler.rb @@ -34,11 +34,12 @@ def call(*args) if attributes.empty? ROM::OpenStruct else - build_class(name, ROM::Struct, ns) do |klass| - attributes.each do |attr_name, type| - klass.attribute(attr_name, type) - end + klass = get_class(name, ns) || build_class(name, ROM::Struct, ns) + attributes.each do |attr_name, type| + klass.attribute(attr_name, type) end + + klass end end end @@ -95,6 +96,13 @@ def visit_enum(node) visit(type_node) end + # @api private + def get_class(name, ns) + ns.const_get(class_name(name)) + rescue NameError + nil + end + # @api private def build_class(name, parent, ns, &block) Dry::Core::ClassBuilder. diff --git a/mapper/spec/unit/rom/struct_compiler_spec.rb b/mapper/spec/unit/rom/struct_compiler_spec.rb index cc709ddae..50568ddc4 100644 --- a/mapper/spec/unit/rom/struct_compiler_spec.rb +++ b/mapper/spec/unit/rom/struct_compiler_spec.rb @@ -11,6 +11,10 @@ def attr_ast(name, type, **opts) [:users, [[:attribute, attr_ast(:id, :Integer)], [:attribute, attr_ast(:name, :String)]]] end + before do + ROM::Struct.send(:remove_const, :User) if ROM::Struct.constants.include?(:User) + end + context 'ROM::Struct' do it 'generates a struct for a given relation name and columns' do struct = struct_compiler[*input, ROM::Struct]