Skip to content

Commit 040bb9e

Browse files
authored
enhancement: Detect polymorphic associations in generator (#3645)
* Chceck potential polymorphic association * Fix issues in recource generator * Change generator option * small changes * few changes * fix some rubocop request changes * next changes * request changes * Change generator * Next attempt to fix finding polymorphic associations * fix standardrb * small changes * delete debugger * change order in generate_fields * optymalize code * test spec * Add comments * final changes * fix standardrb * fix spec and optymalize code * fix spec * back changes from review * fix * final request changes * optymalize code * add tyes to spec and try to reduce complexity * Fix spec * fix field options * fix field options * Request changes * fix bug with types * Delete changes in application_record and create new class in resource generator to handle inspect * fix standardrb fail * fix whitespace * Add comments
1 parent ef879ed commit 040bb9e

File tree

2 files changed

+65
-5
lines changed

2 files changed

+65
-5
lines changed

lib/generators/avo/resource_generator.rb

+43-5
Original file line numberDiff line numberDiff line change
@@ -185,11 +185,34 @@ def fields_from_model_tags
185185

186186
def fields_from_model_associations
187187
associations.each do |name, association|
188-
fields[name] = if association.is_a? ActiveRecord::Reflection::ThroughReflection
189-
field_from_through_association(association)
190-
else
191-
::Avo::Mappings::ASSOCIATIONS_MAPPING[association.class]
192-
end
188+
fields[name] =
189+
if association.polymorphic?
190+
field_with_polymorphic_association(association)
191+
elsif association.is_a?(ActiveRecord::Reflection::ThroughReflection)
192+
field_from_through_association(association)
193+
else
194+
::Avo::Mappings::ASSOCIATIONS_MAPPING[association.class]
195+
end
196+
end
197+
end
198+
199+
def field_with_polymorphic_association(association)
200+
Rails.application.eager_load! unless Rails.application.config.eager_load
201+
202+
types = polymorphic_association_types(association)
203+
204+
{
205+
field: "belongs_to",
206+
options: {
207+
polymorphic_as: ":#{association.name}",
208+
types: types.presence || "[] # Types weren't computed correctly. Please configure them."
209+
}
210+
}
211+
end
212+
213+
def polymorphic_association_types(association)
214+
ActiveRecord::Base.descendants.filter_map do |model|
215+
Inspector.new(model.name) if model.reflect_on_all_associations(:has_many).any? { |assoc| assoc.options[:as] == association.name }
193216
end
194217
end
195218

@@ -293,5 +316,20 @@ def field(name, type)
293316
end
294317
end
295318
end
319+
320+
# This class modifies the inspect function to correctly handle polymorphic associations.
321+
# It is used in the polymorphic_association_types function.
322+
# Without modification: Model(id: integer, name: string)
323+
# After modification: Model
324+
class Inspector
325+
attr_accessor :name
326+
def initialize(name)
327+
@name = name
328+
end
329+
330+
def inspect
331+
name
332+
end
333+
end
296334
end
297335
end

spec/features/avo/generators/resource_generator_spec.rb

+22
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,28 @@
4646
end
4747
end
4848
end
49+
50+
context "when generating resources with polymorphic associations" do
51+
it "generates commented polymorphic fields" do
52+
files = [
53+
Rails.root.join("app", "avo", "resources", "review.rb").to_s,
54+
Rails.root.join("app", "controllers", "avo", "reviews_controller.rb").to_s
55+
]
56+
57+
keeping_original_files(files) do
58+
Rails::Generators.invoke("avo:resource", ["review", "-q", "-s"], {destination_root: Rails.root})
59+
60+
# Types load in different order every time
61+
expect(File.read(files[0])).to include("field :reviewable, as: :belongs_to, polymorphic_as: :reviewable, types:")
62+
expect(File.read(files[0])).to include("Team")
63+
expect(File.read(files[0])).to include("Project")
64+
expect(File.read(files[0])).to include("Post")
65+
expect(File.read(files[0])).to include("Fish")
66+
67+
check_files_and_clean_up files
68+
end
69+
end
70+
end
4971
end
5072

5173
def keeping_original_files(files)

0 commit comments

Comments
 (0)