Skip to content

Commit aca82fa

Browse files
authored
Merge cbc4c3e into a905744
2 parents a905744 + cbc4c3e commit aca82fa

File tree

3 files changed

+38
-42
lines changed

3 files changed

+38
-42
lines changed

lib/rest_framework/routers.rb

Lines changed: 25 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ class Mapper
66
# Internal helper to take extra_actions hash and convert to a consistent format.
77
protected def _parse_extra_actions(extra_actions)
88
return (extra_actions || {}).map do |k,v|
9-
kwargs = {}
9+
kwargs = {action: k}
1010
path = k
1111

1212
# Convert structure to path/methods/kwargs.
@@ -25,11 +25,6 @@ class Mapper
2525
path = v.delete(:path)
2626
end
2727

28-
# Set the action to be the action key unless it's already defined.
29-
if !kwargs[:action]
30-
kwargs[:action] = k
31-
end
32-
3328
# Pass any further kwargs to the underlying Rails interface.
3429
kwargs = kwargs.merge(v)
3530
elsif v.is_a?(Symbol) || v.is_a?(String)
@@ -77,6 +72,16 @@ class Mapper
7772
return controller
7873
end
7974

75+
# Interal interface for routing extra actions.
76+
protected def _route_extra_actions(actions, &block)
77+
actions.each do |action_config|
78+
action_config[:methods].each do |m|
79+
public_send(m, action_config[:path], **action_config[:kwargs])
80+
end
81+
yield if block_given?
82+
end
83+
end
84+
8085
# Internal core implementation of the `rest_resource(s)` router, both singular and plural.
8186
# @param default_singular [Boolean] the default plurality of the resource if the plurality is
8287
# not otherwise defined by the controller
@@ -105,28 +110,20 @@ class Mapper
105110
end
106111
resource_method = singular ? :resource : :resources
107112

108-
# call either `resource` or `resources`, passing appropriate modifiers
113+
# Call either `resource` or `resources`, passing appropriate modifiers.
109114
skip_undefined = kwargs.delete(:skip_undefined) || true
110115
skip = controller_class.get_skip_actions(skip_undefined: skip_undefined)
111116
public_send(resource_method, name, except: skip, **kwargs) do
112117
if controller_class.respond_to?(:extra_member_actions)
113118
member do
114119
actions = self._parse_extra_actions(controller_class.extra_member_actions)
115-
actions.each do |action_config|
116-
action_config[:methods].each do |m|
117-
public_send(m, action_config[:path], **action_config[:kwargs])
118-
end
119-
end
120+
_route_extra_actions(actions)
120121
end
121122
end
122123

123124
collection do
124125
actions = self._parse_extra_actions(controller_class.extra_actions)
125-
actions.each do |action_config|
126-
action_config[:methods].each do |m|
127-
public_send(m, action_config[:path], **action_config[:kwargs])
128-
end
129-
end
126+
_route_extra_actions(actions)
130127
end
131128

132129
yield if block_given?
@@ -150,6 +147,7 @@ def rest_resources(*names, **kwargs, &block)
150147
# Route a controller without the default resourceful paths.
151148
def rest_route(name=nil, **kwargs, &block)
152149
controller = kwargs.delete(:controller) || name
150+
route_root_to = kwargs.delete(:route_root_to)
153151
if controller.is_a?(Class)
154152
controller_class = controller
155153
else
@@ -162,42 +160,27 @@ def rest_route(name=nil, **kwargs, &block)
162160
# Route actions using the resourceful router, but skip all builtin actions.
163161
actions = self._parse_extra_actions(controller_class.extra_actions)
164162
public_send(:resource, name, only: [], **kwargs) do
165-
actions.each do |action_config|
166-
action_config[:methods].each do |m|
167-
public_send(m, action_config[:path], **action_config[:kwargs])
168-
end
169-
yield if block_given?
163+
# Route a root for this resource.
164+
if route_root_to
165+
get '', action: route_root_to
170166
end
167+
168+
_route_extra_actions(actions, &block)
171169
end
172170
end
173171

174172
# Route a controller's `#root` to '/' in the current scope/namespace, along with other actions.
175-
# @param name [Symbol] the snake_case name of the controller
176173
def rest_root(name=nil, **kwargs, &block)
177174
# By default, use RootController#root.
178175
root_action = kwargs.delete(:action) || :root
179176
controller = kwargs.delete(:controller) || name || :root
180177

181-
# Route the root.
182-
get name.to_s, controller: controller, action: root_action
183-
184-
# Route any additional actions.
185-
controller_class = self._get_controller_class(controller, pluralize: false)
186-
actions = self._parse_extra_actions(controller_class.extra_actions)
187-
actions.each do |action_config|
188-
# Add :action unless kwargs defines it.
189-
unless action_config[:kwargs].key?(:action)
190-
action_config[:kwargs][:action] = action_config[:path]
191-
end
178+
# Remove path if name is nil (routing to the root of current namespace).
179+
unless name
180+
kwargs[:path] = ''
181+
end
192182

193-
action_config[:methods].each do |m|
194-
public_send(
195-
m,
196-
File.join(name.to_s, action_config[:path].to_s),
197-
controller: controller,
198-
**action_config[:kwargs],
199-
)
200-
end
183+
return rest_route(controller, route_root_to: root_action, **kwargs) do
201184
yield if block_given?
202185
end
203186
end

test/app/controllers/api1_controller.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,15 @@
22
class Api1Controller < ApplicationController
33
include RESTFramework::BaseControllerMixin
44

5+
self.extra_actions = {test: :get}
6+
57
def root
68
api_response({message: "Welcome to your custom API1 root!"})
79
end
10+
11+
def test
12+
api_response({message: "Test successful!"})
13+
end
814
end
915

1016
module Api1

test/test/integration/api1_routing_test.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@ def test_can_get_root
1010
assert_response :success
1111
end
1212

13+
def can_get_root_test
14+
get '/api1/test'
15+
assert_response :success
16+
get '/api1/test.json'
17+
assert_response :success
18+
end
19+
1320
def test_can_get_things
1421
get '/api1/things'
1522
assert_response :success

0 commit comments

Comments
 (0)