Skip to content

Commit

Permalink
Refs #37825 - Fix resource nesting for PreloadScopesBuilder
Browse files Browse the repository at this point in the history
Without this patch Ansible-related scopes for Host::Managed.includes()
would look like:
[ { host_ansible_roles: :ansible_roles }, { ansible_role: [{ ansible_variables:
[:lookup_values] }] } ], which for some reason worked before Rails 7.
After this patch, it looks like:
[ { host_ansible_roles: { ansible_role: [{ ansible_variables:
[:lookup_values] }] } } ].
  • Loading branch information
ofedoren committed Oct 16, 2024
1 parent e0a011f commit 3f465c5
Showing 1 changed file with 11 additions and 5 deletions.
16 changes: 11 additions & 5 deletions app/services/foreman/preload_scopes_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,22 @@ def preload_scopes
end

def build_scopes(model, ignore: [], assoc_name: nil)
scopes = dependent_associations(model).map do |assoc|
scopes = dependent_associations(model, ignore: ignore).map do |assoc|
next if ignore.include?(assoc.name)

dep_associations = dependent_associations(assoc.klass)
if dep_associations.any?
ignore += dep_associations.select { |to_ignore| to_ignore.options.key?(:through) }.map(&:name)
ignore << assoc.name
dep_scopes = build_scopes(assoc.klass, ignore: ignore, assoc_name: assoc.name)
if assoc.options.key?(:through) && dep_scopes.is_a?(Hash)
next { assoc.options[:through] => assoc.source_reflection_name }.merge(dep_scopes)
if assoc.options.key?(:through)
deps = dependent_associations(assoc.source_reflection.klass, ignore: ignore)
if deps.any?
dep_scopes = build_scopes(assoc.source_reflection.klass, ignore: ignore, assoc_name: assoc.source_reflection_name)
next { assoc.options[:through] => dep_scopes }
else
next { assoc.options[:through] => assoc.source_reflection_name }
end
end
next dep_scopes
end
Expand All @@ -46,9 +52,9 @@ def build_scopes(model, ignore: [], assoc_name: nil)
scopes.empty? ? assoc_name : { assoc_name => scopes }
end

def dependent_associations(model)
def dependent_associations(model, ignore: [])
model.reflect_on_all_associations.select do |assoc|
(assoc.options.values & [:destroy, :delete_all, :destroy_async]).any?
!ignore.include?(assoc.name) && (assoc.options.values & [:destroy, :delete_all, :destroy_async]).any?
end
end
end
Expand Down

0 comments on commit 3f465c5

Please sign in to comment.