Class: ActionDispatch::Routing::Mapper

Inherits:
Object
  • Object
show all
Defined in:
lib/rest_framework/routers.rb

Instance Method Summary collapse

Instance Method Details

#_rrf_controller_class(name) ⇒ Object

Resolve a controller class from a route name and the current scope. The name must match the controller exactly (camelized, plus Controller) — there is no pluralization fallback.



7
8
9
10
# File 'lib/rest_framework/routers.rb', line 7

def _rrf_controller_class(name)
  mod = @scope[:module] ? @scope[:module].to_s.camelize.constantize : Object
  mod.const_get("#{name.to_s.camelize}Controller")
end

#_rrf_rest_route(name, **kwargs) ⇒ Object

Route a single controller from its action store.



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/rest_framework/routers.rb', line 48

def _rrf_rest_route(name, **kwargs)
  controller = kwargs.delete(:controller) || name
  if controller.is_a?(Class)
    controller_class = controller
  else
    controller_class = self._rrf_controller_class(controller)
  end

  # Set controller if it's not explicitly set.
  kwargs[:controller] = name unless kwargs[:controller]

  has_model = !!controller_class.model
  singular = controller_class.singular
  actions = controller_class.actions
  member_actions = controller_class.member_actions

  # Use `resources` (plural) for plural model controllers to get the member `:id` scope; use
  # `resource` (singular) for everything else.
  resource_method = (has_model && !singular) ? :resources : :resource

  public_send(resource_method, name, only: [], **kwargs) do
    if has_model
      if singular
        # Singular model controller: actions and member actions are the same.
        self._rrf_route_actions(actions)
        self._rrf_route_actions(member_actions)
      else
        # Plural model controller: route collection/member actions separately.
        collection { self._rrf_route_actions(actions) }
        member { self._rrf_route_actions(member_actions) }
      end
    else
      # Non-model controller: only actions (there is no member `:id` scope).
      self._rrf_route_actions(actions)
    end

    yield if block_given?
  end
end

#_rrf_route_actions(actions) ⇒ Object

Route each action from a controller's action store.



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/rest_framework/routers.rb', line 13

def _rrf_route_actions(actions)
  actions.each_value do |spec|
    # Delegated actions keep their declared action name (so routing and OpenAPI show the real
    # name); `method_for_action` redirects dispatch to `rrf_delegate`, which needs the scope.
    kwargs = spec.kwargs
    if !spec.builtin && spec.&.[](:delegate)
      kwargs = kwargs.merge(rrf_delegate_scope: spec.type)
    end

    spec.methods.each do |m|
      public_send(m, spec.path, action: spec.name, **kwargs)
    end

    # Record non-builtin (extra) actions and their metadata for the browsable API / OpenAPI.
    next if spec.builtin

    key = "#{@scope[:path]}/#{spec.path}"
    RESTFramework::EXTRA_ACTION_ROUTES.add(key)
    RESTFramework::ROUTE_METADATA[key] = spec. if spec.
  end
end

#rest_route(*names, **kwargs, &block) ⇒ Object

Route one or more controllers from their action stores. Plural model controllers get collection/member scopes; singular and non-model controllers route everything at the root. Passing several names condenses simple routes into one call; per-name options (path:, as:, controller:, and a block) only apply to a single name.



39
40
41
42
43
44
45
# File 'lib/rest_framework/routers.rb', line 39

def rest_route(*names, **kwargs, &block)
  if names.size > 1 && (block || (kwargs.keys & [ :path, :as, :controller ]).any?)
    raise ArgumentError, "rest_route: options and a block require a single name"
  end

  names.each { |name| _rrf_rest_route(name, **kwargs, &block) }
end