Module: Plutonium::Core::Controllers::AssociationResolver

Included in:
Plutonium::Core::Controller
Defined in:
lib/plutonium/core/controllers/association_resolver.rb

Overview

Resolves target classes/instances to association names on a parent model.

This module handles the mapping between resource classes and their association names when generating nested resource URLs. It supports:

  • Explicit association names (symbols)

  • Class-based resolution with namespace fallback

  • Instance-based resolution

Examples:

Explicit association

resolve_association(:comments, @post) # => :comments

Class-based resolution

resolve_association(Comment, @post) # => :comments

Namespaced class resolution

resolve_association(Blogging::Comment, @post) # => :comments (tries :blogging_comments first)

Defined Under Namespace

Classes: AmbiguousAssociationError

Instance Method Summary collapse

Instance Method Details

#resolve_association(target, parent) ⇒ Symbol

Resolves a target to an association name on the parent

Parameters:

  • target (Class, Object, Symbol)

    The target class, instance, or association name

  • parent (Object)

    The parent instance

Returns:

  • (Symbol)

    The resolved association name

Raises:



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/plutonium/core/controllers/association_resolver.rb', line 33

def resolve_association(target, parent)
  return target if target.is_a?(Symbol)

  target_class = target.is_a?(Class) ? target : target.class
  candidates = association_candidates_for(target_class)

  matching = candidates.filter_map do |assoc_name|
    assoc = parent.class.reflect_on_association(assoc_name)
    assoc_name if assoc && assoc.klass >= target_class
  end

  case matching.size
  when 0
    raise ArgumentError,
      "No association found for #{target_class} on #{parent.class}. " \
      "Tried: #{candidates.join(", ")}"
  when 1
    matching.first
  else
    raise AmbiguousAssociationError,
      "Multiple associations to #{target_class} on #{parent.class}: #{matching.join(", ")}. " \
      "Please specify explicitly using a symbol: resource_url_for(:association_name, parent: ...)"
  end
end