modular_routes 0.2.0 → 0.3.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 +47 -20
- data/README.md +69 -24
- data/lib/modular_routes/builder.rb +18 -1
- data/lib/modular_routes/routable/concerns.rb +17 -0
- data/lib/modular_routes/routable.rb +1 -0
- data/lib/modular_routes/scopable/concern.rb +32 -0
- data/lib/modular_routes/scopable/resource.rb +9 -0
- data/lib/modular_routes/scopable.rb +1 -0
- data/lib/modular_routes/version.rb +1 -1
- data/lib/modular_routes.rb +2 -0
- data/modular_routes.gemspec +1 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 735442d6f4629c4b130223eeffdc78e817d2dc183acb01cf541a2174411cf02b
|
4
|
+
data.tar.gz: 9d03465ec7092e08236ece0e73f3fd90d6cf43832ea581e7c0f465f072f4cc7c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4ebb16561f04f2e6648ea42a7eb29cb2077f8fd6b0e8bf35a28e655d7d39cd0983e9d181612e7d52305bd73acd659157de400929e16d8801148d64dc197767b7
|
7
|
+
data.tar.gz: 3c7f422084864aaf10ea89fbe62bd55158d4947df249f07c4e111b3fb2fb4de40c82453984e92d5a837a7242ec200573f15282def879cf7a9f078496e4c20da7
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,30 @@
|
|
1
|
+
## [v0.3.0] - 2021-08-30
|
2
|
+
|
3
|
+
**NEW**
|
4
|
+
|
5
|
+
- `root` helper will raise a syntax error indicating that it should be used outside of `modular_routes` block.
|
6
|
+
|
7
|
+
- `concern` and `concerns` support:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
modular_routes do
|
11
|
+
concern :commentable do
|
12
|
+
resource :comments
|
13
|
+
end
|
14
|
+
|
15
|
+
concern :activatable do
|
16
|
+
member do
|
17
|
+
put :activate
|
18
|
+
put :deactivate
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
resources :articles, concerns: :activatable do
|
23
|
+
concerns :commentable
|
24
|
+
end
|
25
|
+
end
|
26
|
+
```
|
27
|
+
|
1
28
|
## [v0.2.0] - 2021-07-21
|
2
29
|
|
3
30
|
**REMOVED**
|
@@ -9,11 +36,11 @@
|
|
9
36
|
- `modular_routes` helper was added to fix the problems encountered on the previous helper. Check the example below:
|
10
37
|
|
11
38
|
```ruby
|
12
|
-
|
13
|
-
|
39
|
+
modular_routes do
|
40
|
+
resources :books
|
14
41
|
|
15
|
-
|
16
|
-
|
42
|
+
get :about, to: "about#index"
|
43
|
+
end
|
17
44
|
```
|
18
45
|
|
19
46
|
The idea was to bring simplicity and proximity to what you already write in your routes file.
|
@@ -21,9 +48,9 @@
|
|
21
48
|
- `namespace` support`
|
22
49
|
|
23
50
|
```ruby
|
24
|
-
|
25
|
-
|
26
|
-
|
51
|
+
namespace :v1 do
|
52
|
+
resources :books
|
53
|
+
end
|
27
54
|
```
|
28
55
|
|
29
56
|
It falls back to Rails default behavior.
|
@@ -31,13 +58,13 @@
|
|
31
58
|
- `scope` support
|
32
59
|
|
33
60
|
```ruby
|
34
|
-
|
35
|
-
|
36
|
-
|
61
|
+
scope :v1 do
|
62
|
+
resources :books
|
63
|
+
end
|
37
64
|
|
38
|
-
|
39
|
-
|
40
|
-
|
65
|
+
scope module: :v1 do
|
66
|
+
resources :books
|
67
|
+
end
|
41
68
|
```
|
42
69
|
|
43
70
|
It falls back to Rails default behavior. In this example it recognizes `/v1/books` and `/books` expecting `BooksController` and `V1::BooksController` respectively.
|
@@ -45,11 +72,11 @@
|
|
45
72
|
- Nested resources support
|
46
73
|
|
47
74
|
```ruby
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
end
|
75
|
+
modular_routes do
|
76
|
+
resources :books do
|
77
|
+
resources :comments
|
52
78
|
end
|
79
|
+
end
|
53
80
|
```
|
54
81
|
|
55
82
|
It recognizes paths like `/books/1/comments/2`.
|
@@ -57,9 +84,9 @@
|
|
57
84
|
- Standalone (non-resourceful) routes
|
58
85
|
|
59
86
|
```ruby
|
60
|
-
|
61
|
-
|
62
|
-
|
87
|
+
modular_routes do
|
88
|
+
get :about, to: "about#index"
|
89
|
+
end
|
63
90
|
```
|
64
91
|
|
65
92
|
It expects `About::IndexController` to exist in `controllers/about/index_controller.rb`. They don't belong to a resourceful scope.
|
data/README.md
CHANGED
@@ -71,7 +71,7 @@ end
|
|
71
71
|
|
72
72
|
The reason I don't like this approach is that you can end up with a lot of code that are not related to each other in the same file. You can still have it all organized but I believe that it could be better.
|
73
73
|
|
74
|
-
[DHH](http://jeromedalbert.com/how-dhh-organizes-his-rails-controllers/) prefers to keep the RESTful actions (index, new, edit, show, create, update, destroy) inside the same controller and the custom ones in dedicated controllers.
|
74
|
+
[DHH](http://jeromedalbert.com/how-dhh-organizes-his-rails-controllers/) prefers to keep the RESTful actions (index, new, edit, show, create, update, destroy) inside the same controller and the custom ones in dedicated controllers but represented as RESTful actions.
|
75
75
|
|
76
76
|
One way of representing that would be
|
77
77
|
|
@@ -79,8 +79,8 @@ One way of representing that would be
|
|
79
79
|
# routes.rb
|
80
80
|
|
81
81
|
resources :articles do
|
82
|
-
get :stats, on: :collection,
|
83
|
-
post :archive, on: :member,
|
82
|
+
get :stats, on: :collection, to: 'articles/stats#show'
|
83
|
+
post :archive, on: :member, to: 'articles/archive#create'
|
84
84
|
end
|
85
85
|
|
86
86
|
# articles_controller.rb
|
@@ -100,14 +100,14 @@ end
|
|
100
100
|
# articles/archive_controller.rb
|
101
101
|
|
102
102
|
class Articles::ArchiveController
|
103
|
-
def
|
103
|
+
def create
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
107
107
|
# articles/stats_controller.rb
|
108
108
|
|
109
109
|
class Articles::StatsController
|
110
|
-
def
|
110
|
+
def show
|
111
111
|
end
|
112
112
|
end
|
113
113
|
```
|
@@ -263,7 +263,7 @@ The output routes for the code above would be
|
|
263
263
|
| GET | /articles/:id/edit | articles/edit#call | edit_articles_path(:id) |
|
264
264
|
| PATCH/PUT | /articles/:id | articles/update#call | articles_path(:id) |
|
265
265
|
| DELETE | /articles/:id | articles/destroy#call | articles_path(:id) |
|
266
|
-
| POST | /articles/stats | articles/stats#call | stats_articles_path
|
266
|
+
| POST | /articles/stats | articles/stats#call | stats_articles_path |
|
267
267
|
| POST | /articles/:id/archive | articles/archive#call | archive_article_path(:id) |
|
268
268
|
|
269
269
|
### Restricting routes
|
@@ -314,15 +314,15 @@ end
|
|
314
314
|
|
315
315
|
The output routes for that would be
|
316
316
|
|
317
|
-
| HTTP Verb | Path | Controller#Action | Named Route Helper
|
318
|
-
| --------- | -------------------------------- | -------------------------- |
|
319
|
-
| GET | /books/:book_id/reviews | books/reviews/index#call |
|
320
|
-
| GET | /books/:book_id/reviews/new | books/reviews/new#call |
|
321
|
-
| POST | /books/:book_id/reviews | books/reviews/create#call |
|
322
|
-
| GET | /books/:book_id/reviews/:id | books/reviews/show#call |
|
323
|
-
| GET | /books/:book_id/reviews/:id/edit | books/reviews/edit#call |
|
324
|
-
| PATCH/PUT | /books/:book_id/reviews/:id | books/reviews/update#call |
|
325
|
-
| DELETE | /books/:book_id/reviews/:id | books/reviews/destroy#call |
|
317
|
+
| HTTP Verb | Path | Controller#Action | Named Route Helper |
|
318
|
+
| --------- | -------------------------------- | -------------------------- | -------------------------- |
|
319
|
+
| GET | /books/:book_id/reviews | books/reviews/index#call | book_reviews_path |
|
320
|
+
| GET | /books/:book_id/reviews/new | books/reviews/new#call | new_book_review_path |
|
321
|
+
| POST | /books/:book_id/reviews | books/reviews/create#call | book_reviews_path |
|
322
|
+
| GET | /books/:book_id/reviews/:id | books/reviews/show#call | book_review_path(:id) |
|
323
|
+
| GET | /books/:book_id/reviews/:id/edit | books/reviews/edit#call | edit_book_review_path(:id) |
|
324
|
+
| PATCH/PUT | /books/:book_id/reviews/:id | books/reviews/update#call | book_review_path(:id) |
|
325
|
+
| DELETE | /books/:book_id/reviews/:id | books/reviews/destroy#call | book_review_path(:id) |
|
326
326
|
|
327
327
|
### Non-resourceful routes (standalone)
|
328
328
|
|
@@ -374,15 +374,60 @@ modular_routes do
|
|
374
374
|
end
|
375
375
|
```
|
376
376
|
|
377
|
-
| HTTP Verb | Path | Controller#Action | Named Route Helper
|
378
|
-
| --------- | ------------------ | --------------------- |
|
379
|
-
| GET | /v1/books | v1/books/index#call |
|
380
|
-
| GET | /v1/books/new | v1/books/new#call |
|
381
|
-
| POST | /v1/books | v1/books/create#call |
|
382
|
-
| GET | /v1/books/:id | v1/books/show#call |
|
383
|
-
| GET | /v1/books/:id/edit | v1/books/edit#call |
|
384
|
-
| PATCH/PUT | /v1/books/:id | v1/books/update#call |
|
385
|
-
| DELETE | /v1/books/:id | v1/books/destroy#call |
|
377
|
+
| HTTP Verb | Path | Controller#Action | Named Route Helper |
|
378
|
+
| --------- | ------------------ | --------------------- | ---------------------- |
|
379
|
+
| GET | /v1/books | v1/books/index#call | v1_books_path |
|
380
|
+
| GET | /v1/books/new | v1/books/new#call | new_v1_book_path |
|
381
|
+
| POST | /v1/books | v1/books/create#call | v1_books_path |
|
382
|
+
| GET | /v1/books/:id | v1/books/show#call | v1_book_path(:id) |
|
383
|
+
| GET | /v1/books/:id/edit | v1/books/edit#call | edit_v1_book_path(:id) |
|
384
|
+
| PATCH/PUT | /v1/books/:id | v1/books/update#call | v1_book_path(:id) |
|
385
|
+
| DELETE | /v1/books/:id | v1/books/destroy#call | v1_book_path(:id) |
|
386
|
+
|
387
|
+
### Routing concerns
|
388
|
+
|
389
|
+
When you want to reuse route declarations that are usually associated with a common behavior, you can use concerns declaring blocks like:
|
390
|
+
|
391
|
+
```ruby
|
392
|
+
concern :commentable do
|
393
|
+
resource :comments
|
394
|
+
end
|
395
|
+
|
396
|
+
concern :activatable do
|
397
|
+
member do
|
398
|
+
put :activate
|
399
|
+
put :deactivate
|
400
|
+
end
|
401
|
+
end
|
402
|
+
```
|
403
|
+
|
404
|
+
To use it you can pass it through resource(s) options or calling `concerns` helper inside of a resource(s) block:
|
405
|
+
|
406
|
+
```ruby
|
407
|
+
resources :articles, concerns: :commentable
|
408
|
+
|
409
|
+
resources :articles, concerns: [:activatable]
|
410
|
+
|
411
|
+
# or
|
412
|
+
|
413
|
+
resources :articles, concerns: :activatable do
|
414
|
+
concerns :commentable
|
415
|
+
end
|
416
|
+
```
|
417
|
+
|
418
|
+
The output of that would be:
|
419
|
+
|
420
|
+
| HTTP Verb | Path | Controller#Action | Named Route Helper |
|
421
|
+
| --------- | --------------------------------------- | ------------------------------ | ------------------------------------------- |
|
422
|
+
| GET | /articles/:id/activate | articles/activate#call | activate_article_path |
|
423
|
+
| GET | /articles/:id/deactivate | articles/deactivate#call | deactivate_article_path |
|
424
|
+
| GET | /articles/:article_id/comments | articles/comments/index#call | article_comments_path(:article_id) |
|
425
|
+
| GET | /articles/:article_id/comments/new | articles/comments/new#call | new_article_comment_path (:article_id) |
|
426
|
+
| POST | /articles/:article_id/comments | articles/comments/create#call | article_comments_path(:article_id) |
|
427
|
+
| GET | /articles/:article_id/comments/:id | articles/comments/show#call | article_comment_path(:article_id, :id) |
|
428
|
+
| GET | /articles/:article_id/comments/:id/edit | articles/comments/edit#call | edit_article_comment_path(:article_id, :id) |
|
429
|
+
| PATCH/PUT | /articles/:article_id/comments/:id | articles/comments/update#call | article_comment_path(:article_id, :id) |
|
430
|
+
| DELETE | /articles/:article_id/comments/:id | articles/comments/destroy#call | article_comment_path(:article_id, :id) |
|
386
431
|
|
387
432
|
### API mode
|
388
433
|
|
@@ -25,6 +25,19 @@ module ModularRoutes
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
+
def root(*, **)
|
29
|
+
raise SyntaxError, "You must call `root` outside of `modular_routes` block"
|
30
|
+
end
|
31
|
+
|
32
|
+
def concerns(names)
|
33
|
+
raise SyntaxError, "You must call `concerns` inside of a resource block" unless current_scope
|
34
|
+
|
35
|
+
Array(names).each do |name|
|
36
|
+
concern = Routable.for(:concerns, name)
|
37
|
+
current_scope.add(concern)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
28
41
|
def collection(&block)
|
29
42
|
apply_inner_scope(:collection, &block)
|
30
43
|
end
|
@@ -41,6 +54,10 @@ module ModularRoutes
|
|
41
54
|
apply_scopable(:namespace, namespace_name, options, &block)
|
42
55
|
end
|
43
56
|
|
57
|
+
def concern(concern_name, **options, &block)
|
58
|
+
apply_scopable(:concern, concern_name, options, &block)
|
59
|
+
end
|
60
|
+
|
44
61
|
def scope(*args, **options, &block)
|
45
62
|
apply_scopable(:scope, args, options, &block)
|
46
63
|
end
|
@@ -80,7 +97,7 @@ module ModularRoutes
|
|
80
97
|
block&.call
|
81
98
|
|
82
99
|
@scopes.pop
|
83
|
-
@routes.
|
100
|
+
@routes.push(scopable) unless current_scope
|
84
101
|
end
|
85
102
|
|
86
103
|
private def apply_inner_scope(type)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ModularRoutes
|
4
|
+
module Scopable
|
5
|
+
class Concern
|
6
|
+
def initialize(name, options)
|
7
|
+
@name = name
|
8
|
+
@options = options.except(:api_only)
|
9
|
+
|
10
|
+
@children = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def add(route_or_scope)
|
14
|
+
@children << route_or_scope
|
15
|
+
end
|
16
|
+
|
17
|
+
def resource?
|
18
|
+
true
|
19
|
+
end
|
20
|
+
|
21
|
+
def apply(mapper)
|
22
|
+
block = proc do
|
23
|
+
@children.each { |route_or_scope| route_or_scope.apply(mapper) }
|
24
|
+
end
|
25
|
+
|
26
|
+
mapper.concern(@name, block)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private_constant :Concern
|
31
|
+
end
|
32
|
+
end
|
@@ -13,6 +13,7 @@ module ModularRoutes
|
|
13
13
|
@api_only = options.delete(:api_only)
|
14
14
|
@only = options.delete(:only) { default_actions }
|
15
15
|
@except = options.delete(:except)
|
16
|
+
@concerns = Array(options.delete(:concerns))
|
16
17
|
@options = { module: name, only: [] }.merge(options)
|
17
18
|
end
|
18
19
|
|
@@ -31,6 +32,8 @@ module ModularRoutes
|
|
31
32
|
def apply(mapper)
|
32
33
|
mapper.public_send(resource_type, @name, @options) do
|
33
34
|
@children.each { |route_or_scope| route_or_scope.apply(mapper) }
|
35
|
+
|
36
|
+
apply_concerns(mapper)
|
34
37
|
end
|
35
38
|
|
36
39
|
apply_restful_actions(mapper)
|
@@ -55,6 +58,12 @@ module ModularRoutes
|
|
55
58
|
Routable.for(:restful, action, self).apply(mapper)
|
56
59
|
end
|
57
60
|
end
|
61
|
+
|
62
|
+
private def apply_concerns(mapper)
|
63
|
+
@concerns.each do |concern|
|
64
|
+
Routable.for(:concerns, concern).apply(mapper)
|
65
|
+
end
|
66
|
+
end
|
58
67
|
end
|
59
68
|
|
60
69
|
private_constant :Resource
|
data/lib/modular_routes.rb
CHANGED
@@ -5,10 +5,12 @@ require "action_dispatch"
|
|
5
5
|
require_relative "modular_routes/builder"
|
6
6
|
require_relative "modular_routes/extension"
|
7
7
|
require_relative "modular_routes/routable"
|
8
|
+
require_relative "modular_routes/routable/concerns"
|
8
9
|
require_relative "modular_routes/routable/non_restful"
|
9
10
|
require_relative "modular_routes/routable/restful"
|
10
11
|
require_relative "modular_routes/routable/standalone"
|
11
12
|
require_relative "modular_routes/scopable"
|
13
|
+
require_relative "modular_routes/scopable/concern"
|
12
14
|
require_relative "modular_routes/scopable/namespace"
|
13
15
|
require_relative "modular_routes/scopable/resource"
|
14
16
|
require_relative "modular_routes/scopable/scope"
|
data/modular_routes.gemspec
CHANGED
@@ -16,7 +16,7 @@ Gem::Specification.new do |spec|
|
|
16
16
|
|
17
17
|
spec.metadata["homepage_uri"] = spec.homepage
|
18
18
|
spec.metadata["source_code_uri"] = spec.homepage
|
19
|
-
spec.metadata["changelog_uri"] =
|
19
|
+
spec.metadata["changelog_uri"] = "https://github.com/vitoravelino/modular_routes/blob/main/CHANGELOG.md"
|
20
20
|
|
21
21
|
# Specify which files should be added to the gem when it is released.
|
22
22
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: modular_routes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vítor Avelino
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-08-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -148,10 +148,12 @@ files:
|
|
148
148
|
- lib/modular_routes/builder.rb
|
149
149
|
- lib/modular_routes/extension.rb
|
150
150
|
- lib/modular_routes/routable.rb
|
151
|
+
- lib/modular_routes/routable/concerns.rb
|
151
152
|
- lib/modular_routes/routable/non_restful.rb
|
152
153
|
- lib/modular_routes/routable/restful.rb
|
153
154
|
- lib/modular_routes/routable/standalone.rb
|
154
155
|
- lib/modular_routes/scopable.rb
|
156
|
+
- lib/modular_routes/scopable/concern.rb
|
155
157
|
- lib/modular_routes/scopable/namespace.rb
|
156
158
|
- lib/modular_routes/scopable/resource.rb
|
157
159
|
- lib/modular_routes/scopable/scope.rb
|
@@ -163,7 +165,7 @@ licenses: []
|
|
163
165
|
metadata:
|
164
166
|
homepage_uri: https://github.com/vitoravelino/modular_routes
|
165
167
|
source_code_uri: https://github.com/vitoravelino/modular_routes
|
166
|
-
changelog_uri: https://github.com/vitoravelino/modular_routes
|
168
|
+
changelog_uri: https://github.com/vitoravelino/modular_routes/blob/main/CHANGELOG.md
|
167
169
|
post_install_message:
|
168
170
|
rdoc_options: []
|
169
171
|
require_paths:
|