lotus-router 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +53 -11
- data/lib/lotus/router/version.rb +1 -1
- data/lib/lotus/routing/resource.rb +47 -4
- data/lib/lotus/routing/resource/action.rb +41 -8
- data/lib/lotus/routing/resource/nested.rb +39 -0
- data/lib/lotus/routing/resources.rb +8 -0
- data/lib/lotus/routing/resources/action.rb +20 -0
- data/lotus-router.gemspec +1 -1
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b3fcb5db6c1bdb046aeb93c5d0950301d5ed551d
|
4
|
+
data.tar.gz: 577b5c170f3d469369ce4c43c11782f6f9d6ea3c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 189025ab49239109b74a6f939585d2cdc56b7568a9864c0a82af39fc166a36b8f4f4ae7e5335a53b5ca3bcadd2120b75705ca6dc8d12a1b9bf05501aaa45f652
|
7
|
+
data.tar.gz: 339c1ac13cb39971e7594675646b2c7f2a0baafa96a5bd7b44c16be0ce291d089857abbd797ab6fa6be44fa1b7a279c1d159562acd1d46c60ba97c43779d102f
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,13 @@
|
|
1
1
|
# Lotus::Router
|
2
2
|
Rack compatible HTTP router for Ruby
|
3
3
|
|
4
|
+
## v0.4.0 - 2015-05-15
|
5
|
+
### Added
|
6
|
+
- [Alfonso Uceda Pompa] Nested RESTful resource(s)
|
7
|
+
|
8
|
+
### Changed
|
9
|
+
- [Alfonso Uceda Pompa] RESTful resource(s) have a correct pluralization/singularization for variables and named routes (eg. `/books/:id` is now `:book` instead of `:books`)
|
10
|
+
|
4
11
|
## v0.3.0 - 2015-03-23
|
5
12
|
|
6
13
|
## v0.2.1 - 2015-01-30
|
data/README.md
CHANGED
@@ -407,6 +407,27 @@ router.resource 'profile', controller: 'identity'
|
|
407
407
|
router.path(:profile) # => /profile # Will route to Identity::Show
|
408
408
|
```
|
409
409
|
|
410
|
+
#### Nested Resources
|
411
|
+
|
412
|
+
We can nest resource(s):
|
413
|
+
|
414
|
+
```ruby
|
415
|
+
router = Lotus::Router.new
|
416
|
+
router.resource :identity do
|
417
|
+
resource :avatar
|
418
|
+
resources :api_keys
|
419
|
+
end
|
420
|
+
|
421
|
+
router.path(:identity_avatar) # => /identity/avatar
|
422
|
+
router.path(:new_identity_avatar) # => /identity/avatar/new
|
423
|
+
router.path(:edit_identity_avatar) # => /identity/avatar/new
|
424
|
+
|
425
|
+
router.path(:identity_api_keys) # => /identity/api_keys
|
426
|
+
router.path(:identity_api_key) # => /identity/api_keys/:id
|
427
|
+
router.path(:new_identity_api_key) # => /identity/api_keys/new
|
428
|
+
router.path(:edit_identity_api_key) # => /identity/api_keys/:id/edit
|
429
|
+
```
|
430
|
+
|
410
431
|
|
411
432
|
|
412
433
|
### RESTful Resources:
|
@@ -438,14 +459,14 @@ It will map:
|
|
438
459
|
<td>/flowers/:id</td>
|
439
460
|
<td>Flowers::Show</td>
|
440
461
|
<td>:show</td>
|
441
|
-
<td>:
|
462
|
+
<td>:flower</td>
|
442
463
|
</tr>
|
443
464
|
<tr>
|
444
465
|
<td>GET</td>
|
445
466
|
<td>/flowers/new</td>
|
446
467
|
<td>Flowers::New</td>
|
447
468
|
<td>:new</td>
|
448
|
-
<td>:
|
469
|
+
<td>:new_flower</td>
|
449
470
|
</tr>
|
450
471
|
<tr>
|
451
472
|
<td>POST</td>
|
@@ -459,29 +480,29 @@ It will map:
|
|
459
480
|
<td>/flowers/:id/edit</td>
|
460
481
|
<td>Flowers::Edit</td>
|
461
482
|
<td>:edit</td>
|
462
|
-
<td>:
|
483
|
+
<td>:edit_flower</td>
|
463
484
|
</tr>
|
464
485
|
<tr>
|
465
486
|
<td>PATCH</td>
|
466
487
|
<td>/flowers/:id</td>
|
467
488
|
<td>Flowers::Update</td>
|
468
489
|
<td>:update</td>
|
469
|
-
<td>:
|
490
|
+
<td>:flower</td>
|
470
491
|
</tr>
|
471
492
|
<tr>
|
472
493
|
<td>DELETE</td>
|
473
494
|
<td>/flowers/:id</td>
|
474
495
|
<td>Flowers::Destroy</td>
|
475
496
|
<td>:destroy</td>
|
476
|
-
<td>:
|
497
|
+
<td>:flower</td>
|
477
498
|
</tr>
|
478
499
|
</table>
|
479
500
|
|
480
501
|
|
481
502
|
```ruby
|
482
|
-
router.path(:flowers)
|
483
|
-
router.path(:
|
484
|
-
router.path(:
|
503
|
+
router.path(:flowers) # => /flowers
|
504
|
+
router.path(:flower, id: 23) # => /flowers/23
|
505
|
+
router.path(:edit_flower, id: 23) # => /flowers/23/edit
|
485
506
|
```
|
486
507
|
|
487
508
|
|
@@ -512,8 +533,8 @@ router.resources 'flowers' do
|
|
512
533
|
end
|
513
534
|
end
|
514
535
|
|
515
|
-
router.path(:
|
516
|
-
router.path(:search_flowers)
|
536
|
+
router.path(:toggle_flower, id: 23) # => /flowers/23/toggle
|
537
|
+
router.path(:search_flowers) # => /flowers/search
|
517
538
|
```
|
518
539
|
|
519
540
|
|
@@ -523,7 +544,28 @@ Configure controller:
|
|
523
544
|
router = Lotus::Router.new
|
524
545
|
router.resources 'blossoms', controller: 'flowers'
|
525
546
|
|
526
|
-
router.path(:
|
547
|
+
router.path(:blossom, id: 23) # => /blossoms/23 # Will route to Flowers::Show
|
548
|
+
```
|
549
|
+
|
550
|
+
#### Nested Resources
|
551
|
+
|
552
|
+
We can nest resource(s):
|
553
|
+
|
554
|
+
```ruby
|
555
|
+
router = Lotus::Router.new
|
556
|
+
router.resources :users do
|
557
|
+
resource :avatar
|
558
|
+
resources :favorites
|
559
|
+
end
|
560
|
+
|
561
|
+
router.path(:user_avatar, user_id: 1) # => /users/1/avatar
|
562
|
+
router.path(:new_user_avatar, user_id: 1) # => /users/1/avatar/new
|
563
|
+
router.path(:edit_user_avatar, user_id: 1) # => /users/1/avatar/edit
|
564
|
+
|
565
|
+
router.path(:user_favorites, user_id: 1) # => /users/1/favorites
|
566
|
+
router.path(:user_favorite, user_id: 1, id: 2) # => /users/1/favorites/2
|
567
|
+
router.path(:new_user_favorites, user_id: 1) # => /users/1/favorites/new
|
568
|
+
router.path(:edit_user_favorites, user_id: 1, id: 2) # => /users/1/favorites/2/edit
|
527
569
|
```
|
528
570
|
|
529
571
|
## Testing
|
data/lib/lotus/router/version.rb
CHANGED
@@ -15,6 +15,10 @@ module Lotus
|
|
15
15
|
class Resource
|
16
16
|
include Utils::ClassAttribute
|
17
17
|
|
18
|
+
# @api private
|
19
|
+
# @since 0.4.0
|
20
|
+
NESTED_ROUTES_SEPARATOR = '/'.freeze
|
21
|
+
|
18
22
|
# Set of default routes
|
19
23
|
#
|
20
24
|
# @api private
|
@@ -43,30 +47,69 @@ module Lotus
|
|
43
47
|
class_attribute :collection
|
44
48
|
self.collection = Resource::CollectionAction
|
45
49
|
|
50
|
+
# @api private
|
51
|
+
# @since 0.4.0
|
52
|
+
attr_reader :parent
|
53
|
+
|
46
54
|
# @api private
|
47
55
|
# @since 0.1.0
|
48
|
-
def initialize(router, name, options = {}, &blk)
|
56
|
+
def initialize(router, name, options = {}, parent = nil, &blk)
|
49
57
|
@router = router
|
50
58
|
@name = name
|
59
|
+
@parent = parent
|
51
60
|
@options = Options.new(self.class.actions, options.merge(name: @name))
|
52
61
|
generate(&blk)
|
53
62
|
end
|
54
63
|
|
64
|
+
# Allow nested resources inside resource or resources
|
65
|
+
#
|
66
|
+
# @since 0.4.0
|
67
|
+
#
|
68
|
+
# @see Lotus::Router#resources
|
69
|
+
def resources(name, options = {}, &blk)
|
70
|
+
_resource(Resources, name, options, &blk)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Allow nested resource inside resource or resources
|
74
|
+
#
|
75
|
+
# @since 0.4.0
|
76
|
+
#
|
77
|
+
# @see Lotus::Router#resource
|
78
|
+
def resource(name, options = {}, &blk)
|
79
|
+
_resource(Resource, name, options, &blk)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Return separator
|
83
|
+
#
|
84
|
+
# @api private
|
85
|
+
# @since 0.4.0
|
86
|
+
def wildcard_param(route_param = nil)
|
87
|
+
NESTED_ROUTES_SEPARATOR
|
88
|
+
end
|
89
|
+
|
55
90
|
private
|
91
|
+
|
92
|
+
# @api private
|
93
|
+
# @since 0.4.0
|
94
|
+
def _resource(klass, name, options, &blk)
|
95
|
+
options = options.merge(separator: @options[:separator], namespace: @options[:namespace])
|
96
|
+
klass.new(@router, [@name, name].join(NESTED_ROUTES_SEPARATOR), options, self, &blk)
|
97
|
+
end
|
98
|
+
|
56
99
|
def generate(&blk)
|
57
100
|
instance_eval(&blk) if block_given?
|
58
101
|
|
59
102
|
@options.actions.each do |action|
|
60
|
-
self.class.action.generate(@router, action, @options)
|
103
|
+
self.class.action.generate(@router, action, @options, self)
|
61
104
|
end
|
62
105
|
end
|
63
106
|
|
64
107
|
def member(&blk)
|
65
|
-
self.class.member.new(@router, @options, &blk)
|
108
|
+
self.class.member.new(@router, @options, self, &blk)
|
66
109
|
end
|
67
110
|
|
68
111
|
def collection(&blk)
|
69
|
-
self.class.collection.new(@router, @options, &blk)
|
112
|
+
self.class.collection.new(@router, @options, self, &blk)
|
70
113
|
end
|
71
114
|
end
|
72
115
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'lotus/utils/string'
|
2
2
|
require 'lotus/utils/path_prefix'
|
3
3
|
require 'lotus/utils/class_attribute'
|
4
|
+
require 'lotus/routing/resource/nested'
|
4
5
|
|
5
6
|
module Lotus
|
6
7
|
module Routing
|
@@ -15,6 +16,12 @@ module Lotus
|
|
15
16
|
class Action
|
16
17
|
include Utils::ClassAttribute
|
17
18
|
|
19
|
+
# Nested routes separator
|
20
|
+
#
|
21
|
+
# @api private
|
22
|
+
# @since 0.4.0
|
23
|
+
NESTED_ROUTES_SEPARATOR = '/'.freeze
|
24
|
+
|
18
25
|
# Ruby namespace where lookup for default subclasses.
|
19
26
|
#
|
20
27
|
# @api private
|
@@ -41,25 +48,29 @@ module Lotus
|
|
41
48
|
# @param router [Lotus::Router]
|
42
49
|
# @param action [Lotus::Routing::Resource::Action]
|
43
50
|
# @param options [Hash]
|
51
|
+
# @param resource [Lotus::Routing::Resource, Lotus::Routing::Resources]
|
44
52
|
#
|
45
53
|
# @api private
|
46
54
|
#
|
47
55
|
# @since 0.1.0
|
48
|
-
def self.generate(router, action, options)
|
49
|
-
class_for(action).new(router, options)
|
56
|
+
def self.generate(router, action, options = {}, resource = nil)
|
57
|
+
class_for(action).new(router, options, resource)
|
50
58
|
end
|
51
59
|
|
52
60
|
# Initialize an action
|
53
61
|
#
|
54
62
|
# @param router [Lotus::Router]
|
55
63
|
# @param options [Hash]
|
64
|
+
# @param resource [Lotus::Routing::Resource, Lotus::Routing::Resources]
|
56
65
|
# @param blk [Proc]
|
57
66
|
#
|
58
67
|
# @api private
|
59
68
|
#
|
60
69
|
# @since 0.1.0
|
61
|
-
def initialize(router, options, &blk)
|
62
|
-
@router
|
70
|
+
def initialize(router, options = {}, resource = nil, &blk)
|
71
|
+
@router = router
|
72
|
+
@options = options
|
73
|
+
@resource = resource
|
63
74
|
generate(&blk)
|
64
75
|
end
|
65
76
|
|
@@ -77,6 +88,8 @@ module Lotus
|
|
77
88
|
|
78
89
|
# Resource name
|
79
90
|
#
|
91
|
+
# @return [String]
|
92
|
+
#
|
80
93
|
# @api private
|
81
94
|
# @since 0.1.0
|
82
95
|
#
|
@@ -89,7 +102,7 @@ module Lotus
|
|
89
102
|
#
|
90
103
|
# # 'identity' is the name passed in the @options
|
91
104
|
def resource_name
|
92
|
-
@options[:name]
|
105
|
+
@resource_name ||= @options[:name].to_s
|
93
106
|
end
|
94
107
|
|
95
108
|
# Namespace
|
@@ -157,7 +170,7 @@ module Lotus
|
|
157
170
|
# @api private
|
158
171
|
# @since 0.1.0
|
159
172
|
def rest_path
|
160
|
-
namespace.join(resource_name)
|
173
|
+
namespace.join(_nested_rest_path || resource_name.to_s)
|
161
174
|
end
|
162
175
|
|
163
176
|
# The namespaced name of the action within the whole context of the router.
|
@@ -179,7 +192,7 @@ module Lotus
|
|
179
192
|
# @api private
|
180
193
|
# @since 0.1.0
|
181
194
|
def as
|
182
|
-
namespace.relative_join(
|
195
|
+
namespace.relative_join(_singularized_as, self.class.named_route_separator).to_sym
|
183
196
|
end
|
184
197
|
|
185
198
|
# The name of the RESTful action.
|
@@ -233,10 +246,30 @@ module Lotus
|
|
233
246
|
# # Same for other action names
|
234
247
|
#
|
235
248
|
# @api private
|
236
|
-
# @since
|
249
|
+
# @since 0.4.0
|
237
250
|
def controller_name
|
238
251
|
@options[:controller] || resource_name
|
239
252
|
end
|
253
|
+
|
254
|
+
private
|
255
|
+
|
256
|
+
# Singularize as (helper route)
|
257
|
+
#
|
258
|
+
# @api private
|
259
|
+
# @since 0.4.0
|
260
|
+
def _singularized_as
|
261
|
+
resource_name.split(NESTED_ROUTES_SEPARATOR).map do |name|
|
262
|
+
Lotus::Utils::String.new(name).singularize
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
# Create nested rest path
|
267
|
+
#
|
268
|
+
# @api private
|
269
|
+
# @since 0.4.0
|
270
|
+
def _nested_rest_path
|
271
|
+
Nested.new(resource_name, @resource).to_path
|
272
|
+
end
|
240
273
|
end
|
241
274
|
|
242
275
|
# Collection action
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Lotus
|
2
|
+
module Routing
|
3
|
+
class Resource
|
4
|
+
# Helper class to calculate nested path
|
5
|
+
#
|
6
|
+
# @api private
|
7
|
+
# @since 0.4.0
|
8
|
+
class Nested
|
9
|
+
# @api private
|
10
|
+
# @since 0.4.0
|
11
|
+
SEPARATOR = '/'.freeze
|
12
|
+
|
13
|
+
# @api private
|
14
|
+
# @since 0.4.0
|
15
|
+
def initialize(resource_name, resource)
|
16
|
+
@resource_name = resource_name.to_s.split(SEPARATOR)
|
17
|
+
@resource = resource
|
18
|
+
@path = []
|
19
|
+
_calculate(@resource_name.dup, @resource)
|
20
|
+
end
|
21
|
+
|
22
|
+
# @api private
|
23
|
+
# @since 0.4.0
|
24
|
+
def to_path
|
25
|
+
@path.reverse!.pop
|
26
|
+
@resource_name.zip(@path).flatten.join
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def _calculate(param_wildcard, resource = nil)
|
32
|
+
return if resource.nil?
|
33
|
+
@path << resource.wildcard_param(param_wildcard.pop)
|
34
|
+
_calculate(param_wildcard, resource.parent)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -35,6 +35,14 @@ module Lotus
|
|
35
35
|
# @api private
|
36
36
|
# @since 0.1.0
|
37
37
|
self.collection = Resources::CollectionAction
|
38
|
+
|
39
|
+
# Return wildcard param between separators
|
40
|
+
#
|
41
|
+
# @api private
|
42
|
+
# @since 0.4.0
|
43
|
+
def wildcard_param(route_param = nil)
|
44
|
+
"/:#{ Lotus::Utils::String.new(route_param).singularize }_id/"
|
45
|
+
end
|
38
46
|
end
|
39
47
|
end
|
40
48
|
end
|
@@ -27,6 +27,21 @@ module Lotus
|
|
27
27
|
self.identifier = ':id'.freeze
|
28
28
|
end
|
29
29
|
|
30
|
+
# Pluralize concrete actions
|
31
|
+
#
|
32
|
+
# @api private
|
33
|
+
# @since 0.4.0
|
34
|
+
module PluralizedAction
|
35
|
+
private
|
36
|
+
# The name of the RESTful action.
|
37
|
+
#
|
38
|
+
# @api private
|
39
|
+
# @since 0.4.0
|
40
|
+
def as
|
41
|
+
Lotus::Utils::String.new(super).pluralize
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
30
45
|
# Collection action
|
31
46
|
# It implements #collection within a #resources block.
|
32
47
|
#
|
@@ -34,6 +49,9 @@ module Lotus
|
|
34
49
|
# @since 0.1.0
|
35
50
|
# @see Lotus::Router#resources
|
36
51
|
class CollectionAction < Resource::CollectionAction
|
52
|
+
def as(action_name)
|
53
|
+
Lotus::Utils::String.new(super(action_name)).pluralize
|
54
|
+
end
|
37
55
|
end
|
38
56
|
|
39
57
|
# Member action
|
@@ -66,6 +84,7 @@ module Lotus
|
|
66
84
|
# @since 0.1.0
|
67
85
|
# @see Lotus::Router#resources
|
68
86
|
class Index < Action
|
87
|
+
include PluralizedAction
|
69
88
|
self.verb = :get
|
70
89
|
end
|
71
90
|
|
@@ -83,6 +102,7 @@ module Lotus
|
|
83
102
|
# @since 0.1.0
|
84
103
|
# @see Lotus::Router#resources
|
85
104
|
class Create < Resource::Create
|
105
|
+
include PluralizedAction
|
86
106
|
end
|
87
107
|
|
88
108
|
# Show action
|
data/lotus-router.gemspec
CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.required_ruby_version = '>= 2.0.0'
|
21
21
|
|
22
22
|
spec.add_dependency 'http_router', '~> 0.11'
|
23
|
-
spec.add_dependency 'lotus-utils', '~> 0.4'
|
23
|
+
spec.add_dependency 'lotus-utils', '~> 0.4', '>= 0.4.1'
|
24
24
|
|
25
25
|
spec.add_development_dependency 'bundler', '~> 1.5'
|
26
26
|
spec.add_development_dependency 'minitest', '~> 5'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lotus-router
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Luca Guidi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-05-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: http_router
|
@@ -31,6 +31,9 @@ dependencies:
|
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0.4'
|
34
|
+
- - ">="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 0.4.1
|
34
37
|
type: :runtime
|
35
38
|
prerelease: false
|
36
39
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -38,6 +41,9 @@ dependencies:
|
|
38
41
|
- - "~>"
|
39
42
|
- !ruby/object:Gem::Version
|
40
43
|
version: '0.4'
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 0.4.1
|
41
47
|
- !ruby/object:Gem::Dependency
|
42
48
|
name: bundler
|
43
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -102,6 +108,7 @@ files:
|
|
102
108
|
- lib/lotus/routing/parsing/parser.rb
|
103
109
|
- lib/lotus/routing/resource.rb
|
104
110
|
- lib/lotus/routing/resource/action.rb
|
111
|
+
- lib/lotus/routing/resource/nested.rb
|
105
112
|
- lib/lotus/routing/resource/options.rb
|
106
113
|
- lib/lotus/routing/resources.rb
|
107
114
|
- lib/lotus/routing/resources/action.rb
|