hanami-router 2.0.0.alpha1 → 2.0.0.alpha2
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 +16 -0
- data/README.md +11 -401
- data/hanami-router.gemspec +2 -4
- data/lib/hanami/middleware/body_parser.rb +2 -2
- data/lib/hanami/middleware/body_parser/class_interface.rb +10 -4
- data/lib/hanami/middleware/body_parser/json_parser.rb +4 -4
- data/lib/hanami/router.rb +525 -1040
- data/lib/hanami/router/block.rb +88 -0
- data/lib/hanami/router/error.rb +67 -0
- data/lib/hanami/router/node.rb +93 -0
- data/lib/hanami/router/params.rb +35 -0
- data/lib/hanami/router/prefix.rb +65 -0
- data/lib/hanami/router/recognized_route.rb +92 -0
- data/lib/hanami/router/redirect.rb +28 -0
- data/lib/hanami/router/segment.rb +19 -0
- data/lib/hanami/router/trie.rb +63 -0
- data/lib/hanami/router/url_helpers.rb +40 -0
- data/lib/hanami/router/version.rb +2 -1
- metadata +17 -48
- data/lib/hanami/routing.rb +0 -193
- data/lib/hanami/routing/endpoint.rb +0 -213
- data/lib/hanami/routing/endpoint_resolver.rb +0 -242
- data/lib/hanami/routing/prefix.rb +0 -102
- data/lib/hanami/routing/recognized_route.rb +0 -233
- data/lib/hanami/routing/resource.rb +0 -121
- data/lib/hanami/routing/resource/action.rb +0 -427
- data/lib/hanami/routing/resource/nested.rb +0 -44
- data/lib/hanami/routing/resource/options.rb +0 -76
- data/lib/hanami/routing/resources.rb +0 -50
- data/lib/hanami/routing/resources/action.rb +0 -161
- data/lib/hanami/routing/routes_inspector.rb +0 -223
- data/lib/hanami/routing/scope.rb +0 -112
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '078b6fde8c274fe1d60ae480f8b9aec21e3c765daf8ba58f10b1b30a2d0c2135'
|
4
|
+
data.tar.gz: 941ad1968db99f130f18ef37ba12798e882e80b84aeb9974780edeabd446dcfb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9091771edcea709bf395654175c7a4f8c1f961d85d66f553db6591d7e1c6675cea38cfdc393e5438e219edb75c75965d4a37727e2da69cdbe1d57ce6756523b7
|
7
|
+
data.tar.gz: 130e577dd27732b4b74acc147a9fbaa444b682546092acd6ed849347c94edcbd779193917b66f4444dd4faf1d7f35ae5dc6755eada2b783ba5d62aa0b7d9c004
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,17 @@
|
|
1
1
|
# Hanami::Router
|
2
2
|
Rack compatible HTTP router for Ruby
|
3
3
|
|
4
|
+
## v2.0.0.alpha2 - 2020-02-19
|
5
|
+
### Added
|
6
|
+
- [Luca Guidi] Block syntax. Routes definition accept a block which returning value is the body of the Rack response.
|
7
|
+
- [Luca Guidi] Added `resolver:` option to `Hanami::Router#initialize` to provide your own strategy to load endpoints.
|
8
|
+
|
9
|
+
### Changed
|
10
|
+
- [Luca Guidi] Removed `Hanami::Router#resource` and `#resources`.
|
11
|
+
- [Luca Guidi] Removed loading of routes endpoints.
|
12
|
+
- [Luca Guidi] Removed `inflector:` from `Hanami::Router#initialize`
|
13
|
+
- [Luca Guidi] Removed `scheme:`, `host:`, `port:` from `Hanami::Router#initialize`, use `base_url:` instead.
|
14
|
+
|
4
15
|
## v2.0.0.alpha1 - 2019-01-30
|
5
16
|
### Added
|
6
17
|
- [Luca Guidi] Introduce `Hanami::Router#scope` to support single routing tier for Hanami
|
@@ -17,6 +28,11 @@ Rack compatible HTTP router for Ruby
|
|
17
28
|
- [Luca Guidi] All the code base respects the frozen string pragma
|
18
29
|
- [Luca Guidi] `Hanami::Router#initialize` requires `configuration:` option if routes endpoints are `Hanami::Action` subclasses
|
19
30
|
|
31
|
+
## v1.3.2 - 2019-02-13
|
32
|
+
### Added
|
33
|
+
- [Luca Guidi] Official support for Ruby: MRI 2.7
|
34
|
+
- [Luca Guidi] Support `rack` 2.1
|
35
|
+
|
20
36
|
## v1.3.1 - 2019-01-18
|
21
37
|
### Added
|
22
38
|
- [Luca Guidi] Official support for Ruby: MRI 2.6
|
data/README.md
CHANGED
@@ -5,7 +5,7 @@ Rack compatible, lightweight and fast HTTP Router for Ruby and [Hanami](http://h
|
|
5
5
|
## Status
|
6
6
|
|
7
7
|
[](https://badge.fury.io/rb/hanami-router)
|
8
|
-
[](https://ci.hanamirb.org/hanami/router)
|
9
9
|
[](https://circleci.com/gh/hanami/router/tree/master)
|
10
10
|
[](https://codecov.io/gh/hanami/router)
|
11
11
|
[](https://depfu.com/github/hanami/router?project=Bundler)
|
@@ -30,7 +30,7 @@ __Hanami::Router__ supports Ruby (MRI) 2.5+
|
|
30
30
|
Add this line to your application's Gemfile:
|
31
31
|
|
32
32
|
```ruby
|
33
|
-
gem
|
33
|
+
gem "hanami-router"
|
34
34
|
```
|
35
35
|
|
36
36
|
And then execute:
|
@@ -81,41 +81,17 @@ Hanami::Router.new do
|
|
81
81
|
get "/lambda", to: ->(env) { [200, {}, ["World"]] }
|
82
82
|
get "/dashboard", to: Dashboard::Index
|
83
83
|
get "/rack-app", to: RackApp.new
|
84
|
-
get "/flowers", to: "flowers#index"
|
85
|
-
get "/flowers/:id", to: "flowers#show"
|
86
84
|
|
87
85
|
redirect "/legacy", to: "/"
|
88
86
|
|
89
87
|
mount Api::App, at: "/api"
|
90
88
|
|
91
|
-
|
89
|
+
scope "admin" do
|
92
90
|
get "/users", to: Users::Index
|
93
91
|
end
|
94
|
-
|
95
|
-
resource "identity" do
|
96
|
-
member do
|
97
|
-
get "/avatar"
|
98
|
-
end
|
99
|
-
|
100
|
-
collection do
|
101
|
-
get "/api_keys"
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
resources "robots" do
|
106
|
-
member do
|
107
|
-
patch "/activate"
|
108
|
-
end
|
109
|
-
|
110
|
-
collection do
|
111
|
-
get "/search"
|
112
|
-
end
|
113
|
-
end
|
114
92
|
end
|
115
93
|
```
|
116
94
|
|
117
|
-
|
118
|
-
|
119
95
|
### Fixed string matching:
|
120
96
|
|
121
97
|
```ruby
|
@@ -124,8 +100,6 @@ Hanami::Router.new do
|
|
124
100
|
end
|
125
101
|
```
|
126
102
|
|
127
|
-
|
128
|
-
|
129
103
|
### String matching with variables:
|
130
104
|
|
131
105
|
```ruby
|
@@ -134,8 +108,6 @@ Hanami::Router.new do
|
|
134
108
|
end
|
135
109
|
```
|
136
110
|
|
137
|
-
|
138
|
-
|
139
111
|
### Variables Constraints:
|
140
112
|
|
141
113
|
```ruby
|
@@ -144,8 +116,6 @@ Hanami::Router.new do
|
|
144
116
|
end
|
145
117
|
```
|
146
118
|
|
147
|
-
|
148
|
-
|
149
119
|
### String matching with globbing:
|
150
120
|
|
151
121
|
```ruby
|
@@ -154,8 +124,6 @@ Hanami::Router.new do
|
|
154
124
|
end
|
155
125
|
```
|
156
126
|
|
157
|
-
|
158
|
-
|
159
127
|
### String matching with optional tokens:
|
160
128
|
|
161
129
|
```ruby
|
@@ -164,8 +132,6 @@ Hanami::Router.new do
|
|
164
132
|
end
|
165
133
|
```
|
166
134
|
|
167
|
-
|
168
|
-
|
169
135
|
### Support for the most common HTTP methods:
|
170
136
|
|
171
137
|
```ruby
|
@@ -182,8 +148,6 @@ Hanami::Router.new do
|
|
182
148
|
end
|
183
149
|
```
|
184
150
|
|
185
|
-
|
186
|
-
|
187
151
|
### Root:
|
188
152
|
|
189
153
|
```ruby
|
@@ -192,8 +156,6 @@ Hanami::Router.new do
|
|
192
156
|
end
|
193
157
|
```
|
194
158
|
|
195
|
-
|
196
|
-
|
197
159
|
### Redirect:
|
198
160
|
|
199
161
|
```ruby
|
@@ -203,8 +165,6 @@ Hanami::Router.new do
|
|
203
165
|
end
|
204
166
|
```
|
205
167
|
|
206
|
-
|
207
|
-
|
208
168
|
### Named routes:
|
209
169
|
|
210
170
|
```ruby
|
@@ -217,13 +177,12 @@ router.url(:hanami) # => "https://hanamirb.org/hanami"
|
|
217
177
|
```
|
218
178
|
|
219
179
|
|
220
|
-
|
221
|
-
### Prefixed routes:
|
180
|
+
### Scopes:
|
222
181
|
|
223
182
|
```ruby
|
224
183
|
router = Hanami::Router.new do
|
225
|
-
|
226
|
-
|
184
|
+
scope "animals" do
|
185
|
+
scope "mammals" do
|
227
186
|
get "/cats", to: ->(env) { [200, {}, ["Meow!"]] }, as: :cats
|
228
187
|
end
|
229
188
|
end
|
@@ -238,24 +197,15 @@ router.path(:animals_mammals_cats) # => "/animals/mammals/cats"
|
|
238
197
|
|
239
198
|
### Mount Rack applications:
|
240
199
|
|
200
|
+
Mounting a Rack application will forward all kind of HTTP requests to the app,
|
201
|
+
when the request path matches the `at:` path.
|
202
|
+
|
241
203
|
```ruby
|
242
204
|
Hanami::Router.new do
|
243
|
-
mount
|
244
|
-
mount RackTwo, at: "/rack2"
|
245
|
-
mount RackThree.new, at: "/rack3"
|
246
|
-
mount ->(env) {[200, {}, ["Rack Four"]]}, at: "/rack4"
|
247
|
-
mount "dashboard#index", at: "/dashboard"
|
205
|
+
mount MyRackApp.new, at: "/foo"
|
248
206
|
end
|
249
207
|
```
|
250
208
|
|
251
|
-
1. `RackOne` is used as it is (class), because it respond to `.call`
|
252
|
-
2. `RackTwo` is initialized, because it respond to `#call`
|
253
|
-
3. `RackThree` is used as it is (object), because it respond to `#call`
|
254
|
-
4. That Proc is used as it is, because it respond to `#call`
|
255
|
-
5. That string is resolved as `Dashboard::Index` ([Hanami::Controller](https://github.com/hanami/controller) integration)
|
256
|
-
|
257
|
-
|
258
|
-
|
259
209
|
### Duck typed endpoints:
|
260
210
|
|
261
211
|
Everything that responds to `#call` is invoked as it is:
|
@@ -263,45 +213,11 @@ Everything that responds to `#call` is invoked as it is:
|
|
263
213
|
```ruby
|
264
214
|
Hanami::Router.new do
|
265
215
|
get "/hanami", to: ->(env) { [200, {}, ["Hello from Hanami!"]] }
|
266
|
-
get "/middleware", to: Middleware
|
267
216
|
get "/rack-app", to: RackApp.new
|
268
217
|
get "/method", to: ActionControllerSubclass.action(:new)
|
269
218
|
end
|
270
219
|
```
|
271
220
|
|
272
|
-
|
273
|
-
If it's a string, it tries to instantiate a class from it:
|
274
|
-
|
275
|
-
```ruby
|
276
|
-
class RackApp
|
277
|
-
def call(env)
|
278
|
-
# ...
|
279
|
-
end
|
280
|
-
end
|
281
|
-
|
282
|
-
Hanami::Router.new do
|
283
|
-
get "/hanami", to: "rack_app" # it will map to RackApp.new
|
284
|
-
end
|
285
|
-
```
|
286
|
-
|
287
|
-
It also supports Controller + Action syntax:
|
288
|
-
|
289
|
-
```ruby
|
290
|
-
module Flowers
|
291
|
-
class Index < Hanami::Action
|
292
|
-
def handle(*)
|
293
|
-
# ...
|
294
|
-
end
|
295
|
-
end
|
296
|
-
end
|
297
|
-
|
298
|
-
Hanami::Router.new do
|
299
|
-
get "/flowers", to: "flowers#index" # it will map to Flowers::Index.new
|
300
|
-
end
|
301
|
-
```
|
302
|
-
|
303
|
-
|
304
|
-
|
305
221
|
### Implicit Not Found (404):
|
306
222
|
|
307
223
|
```ruby
|
@@ -309,312 +225,6 @@ router = Hanami::Router.new
|
|
309
225
|
router.call(Rack::MockRequest.env_for("/unknown")).status # => 404
|
310
226
|
```
|
311
227
|
|
312
|
-
### Controllers:
|
313
|
-
|
314
|
-
`Hanami::Router` has a special convention for controllers naming.
|
315
|
-
It allows to declare an action as an endpoint, with a special syntax: `<controller>#<action>`.
|
316
|
-
|
317
|
-
```ruby
|
318
|
-
Hanami::Router.new do
|
319
|
-
get "/", to: "welcome#index"
|
320
|
-
end
|
321
|
-
```
|
322
|
-
|
323
|
-
In the example above, the router will look for the `Welcome::Index` action.
|
324
|
-
|
325
|
-
#### Namespaces
|
326
|
-
|
327
|
-
In applications where for maintainability or technical reasons, this convention
|
328
|
-
can't work, `Hanami::Router` can accept a `:namespace` option, which defines the
|
329
|
-
Ruby namespace where to look for actions.
|
330
|
-
|
331
|
-
For instance, given a Hanami full stack application called `Bookshelf`, the
|
332
|
-
controllers are available under `Bookshelf::Controllers`.
|
333
|
-
|
334
|
-
```ruby
|
335
|
-
Hanami::Router.new(namespace: Bookshelf::Controllers) do
|
336
|
-
get "/", to: "welcome#index"
|
337
|
-
end
|
338
|
-
```
|
339
|
-
|
340
|
-
In the example above, the router will look for the `Bookshelf::Controllers::Welcome::Index` action.
|
341
|
-
|
342
|
-
### RESTful Resource:
|
343
|
-
|
344
|
-
```ruby
|
345
|
-
Hanami::Router.new do
|
346
|
-
resource "identity"
|
347
|
-
end
|
348
|
-
```
|
349
|
-
|
350
|
-
It will map:
|
351
|
-
|
352
|
-
<table>
|
353
|
-
<tr>
|
354
|
-
<th>Verb</th>
|
355
|
-
<th>Path</th>
|
356
|
-
<th>Action</th>
|
357
|
-
<th>Name</th>
|
358
|
-
<th>Named Route</th>
|
359
|
-
</tr>
|
360
|
-
<tr>
|
361
|
-
<td>GET</td>
|
362
|
-
<td>/identity</td>
|
363
|
-
<td>Identity::Show</td>
|
364
|
-
<td>:show</td>
|
365
|
-
<td>:identity</td>
|
366
|
-
</tr>
|
367
|
-
<tr>
|
368
|
-
<td>GET</td>
|
369
|
-
<td>/identity/new</td>
|
370
|
-
<td>Identity::New</td>
|
371
|
-
<td>:new</td>
|
372
|
-
<td>:new_identity</td>
|
373
|
-
</tr>
|
374
|
-
<tr>
|
375
|
-
<td>POST</td>
|
376
|
-
<td>/identity</td>
|
377
|
-
<td>Identity::Create</td>
|
378
|
-
<td>:create</td>
|
379
|
-
<td>:identity</td>
|
380
|
-
</tr>
|
381
|
-
<tr>
|
382
|
-
<td>GET</td>
|
383
|
-
<td>/identity/edit</td>
|
384
|
-
<td>Identity::Edit</td>
|
385
|
-
<td>:edit</td>
|
386
|
-
<td>:edit_identity</td>
|
387
|
-
</tr>
|
388
|
-
<tr>
|
389
|
-
<td>PATCH</td>
|
390
|
-
<td>/identity</td>
|
391
|
-
<td>Identity::Update</td>
|
392
|
-
<td>:update</td>
|
393
|
-
<td>:identity</td>
|
394
|
-
</tr>
|
395
|
-
<tr>
|
396
|
-
<td>DELETE</td>
|
397
|
-
<td>/identity</td>
|
398
|
-
<td>Identity::Destroy</td>
|
399
|
-
<td>:destroy</td>
|
400
|
-
<td>:identity</td>
|
401
|
-
</tr>
|
402
|
-
</table>
|
403
|
-
|
404
|
-
If you don't need all the default endpoints, just do:
|
405
|
-
|
406
|
-
```ruby
|
407
|
-
Hanami::Router.new do
|
408
|
-
resource "identity", only: [:edit, :update]
|
409
|
-
end
|
410
|
-
|
411
|
-
#### which is equivalent to:
|
412
|
-
|
413
|
-
Hanami::Router.new do
|
414
|
-
resource "identity", except: [:show, :new, :create, :destroy]
|
415
|
-
end
|
416
|
-
```
|
417
|
-
|
418
|
-
|
419
|
-
If you need extra endpoints:
|
420
|
-
|
421
|
-
```ruby
|
422
|
-
router = Hanami::Router.new do
|
423
|
-
resource "identity" do
|
424
|
-
member do
|
425
|
-
get "avatar" # maps to Identity::Avatar
|
426
|
-
end
|
427
|
-
|
428
|
-
collection do
|
429
|
-
get "authorizations" # maps to Identity::Authorizations
|
430
|
-
end
|
431
|
-
end
|
432
|
-
end
|
433
|
-
|
434
|
-
router.path(:avatar_identity) # => "/identity/avatar"
|
435
|
-
router.path(:authorizations_identity) # => "/identity/authorizations"
|
436
|
-
```
|
437
|
-
|
438
|
-
|
439
|
-
Configure controller:
|
440
|
-
|
441
|
-
```ruby
|
442
|
-
router = Hanami::Router.new do
|
443
|
-
resource "profile", controller: "identity"
|
444
|
-
end
|
445
|
-
|
446
|
-
router.path(:profile) # => "/profile" # Will route to Identity::Show
|
447
|
-
```
|
448
|
-
|
449
|
-
#### Nested Resources
|
450
|
-
|
451
|
-
We can nest resource(s):
|
452
|
-
|
453
|
-
```ruby
|
454
|
-
router = Hanami::Router.new do
|
455
|
-
resource :identity do
|
456
|
-
resource :avatar
|
457
|
-
resources :api_keys
|
458
|
-
end
|
459
|
-
end
|
460
|
-
|
461
|
-
router.path(:identity_avatar) # => "/identity/avatar"
|
462
|
-
router.path(:new_identity_avatar) # => "/identity/avatar/new"
|
463
|
-
router.path(:edit_identity_avatar) # => "/identity/avatar/new"
|
464
|
-
|
465
|
-
router.path(:identity_api_keys) # => "/identity/api_keys"
|
466
|
-
router.path(:identity_api_key, id: 1) # => "/identity/api_keys/:id"
|
467
|
-
router.path(:new_identity_api_key) # => "/identity/api_keys/new"
|
468
|
-
router.path(:edit_identity_api_key, id: 1) # => "/identity/api_keys/:id/edit"
|
469
|
-
```
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
### RESTful Resources:
|
474
|
-
|
475
|
-
```ruby
|
476
|
-
Hanami::Router.new do
|
477
|
-
resources "flowers"
|
478
|
-
end
|
479
|
-
```
|
480
|
-
|
481
|
-
It will map:
|
482
|
-
|
483
|
-
<table>
|
484
|
-
<tr>
|
485
|
-
<th>Verb</th>
|
486
|
-
<th>Path</th>
|
487
|
-
<th>Action</th>
|
488
|
-
<th>Name</th>
|
489
|
-
<th>Named Route</th>
|
490
|
-
</tr>
|
491
|
-
<tr>
|
492
|
-
<td>GET</td>
|
493
|
-
<td>/flowers</td>
|
494
|
-
<td>Flowers::Index</td>
|
495
|
-
<td>:index</td>
|
496
|
-
<td>:flowers</td>
|
497
|
-
</tr>
|
498
|
-
<tr>
|
499
|
-
<td>GET</td>
|
500
|
-
<td>/flowers/:id</td>
|
501
|
-
<td>Flowers::Show</td>
|
502
|
-
<td>:show</td>
|
503
|
-
<td>:flower</td>
|
504
|
-
</tr>
|
505
|
-
<tr>
|
506
|
-
<td>GET</td>
|
507
|
-
<td>/flowers/new</td>
|
508
|
-
<td>Flowers::New</td>
|
509
|
-
<td>:new</td>
|
510
|
-
<td>:new_flower</td>
|
511
|
-
</tr>
|
512
|
-
<tr>
|
513
|
-
<td>POST</td>
|
514
|
-
<td>/flowers</td>
|
515
|
-
<td>Flowers::Create</td>
|
516
|
-
<td>:create</td>
|
517
|
-
<td>:flowers</td>
|
518
|
-
</tr>
|
519
|
-
<tr>
|
520
|
-
<td>GET</td>
|
521
|
-
<td>/flowers/:id/edit</td>
|
522
|
-
<td>Flowers::Edit</td>
|
523
|
-
<td>:edit</td>
|
524
|
-
<td>:edit_flower</td>
|
525
|
-
</tr>
|
526
|
-
<tr>
|
527
|
-
<td>PATCH</td>
|
528
|
-
<td>/flowers/:id</td>
|
529
|
-
<td>Flowers::Update</td>
|
530
|
-
<td>:update</td>
|
531
|
-
<td>:flower</td>
|
532
|
-
</tr>
|
533
|
-
<tr>
|
534
|
-
<td>DELETE</td>
|
535
|
-
<td>/flowers/:id</td>
|
536
|
-
<td>Flowers::Destroy</td>
|
537
|
-
<td>:destroy</td>
|
538
|
-
<td>:flower</td>
|
539
|
-
</tr>
|
540
|
-
</table>
|
541
|
-
|
542
|
-
|
543
|
-
```ruby
|
544
|
-
router.path(:flowers) # => "/flowers"
|
545
|
-
router.path(:flower, id: 23) # => "/flowers/23"
|
546
|
-
router.path(:edit_flower, id: 23) # => "/flowers/23/edit"
|
547
|
-
```
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
If you don't need all the default endpoints, just do:
|
552
|
-
|
553
|
-
```ruby
|
554
|
-
Hanami::Router.new do
|
555
|
-
resources "flowers", only: [:new, :create, :show]
|
556
|
-
end
|
557
|
-
|
558
|
-
#### which is equivalent to:
|
559
|
-
|
560
|
-
Hanami::Router.new do
|
561
|
-
resources "flowers", except: [:index, :edit, :update, :destroy]
|
562
|
-
end
|
563
|
-
```
|
564
|
-
|
565
|
-
|
566
|
-
If you need extra endpoints:
|
567
|
-
|
568
|
-
```ruby
|
569
|
-
router = Hanami::Router.new do
|
570
|
-
resources "flowers" do
|
571
|
-
member do
|
572
|
-
get "toggle" # maps to Flowers::Toggle
|
573
|
-
end
|
574
|
-
|
575
|
-
collection do
|
576
|
-
get "search" # maps to Flowers::Search
|
577
|
-
end
|
578
|
-
end
|
579
|
-
end
|
580
|
-
|
581
|
-
router.path(:toggle_flower, id: 23) # => "/flowers/23/toggle"
|
582
|
-
router.path(:search_flowers) # => "/flowers/search"
|
583
|
-
```
|
584
|
-
|
585
|
-
|
586
|
-
Configure controller:
|
587
|
-
|
588
|
-
```ruby
|
589
|
-
router = Hanami::Router.new do
|
590
|
-
resources "blossoms", controller: "flowers"
|
591
|
-
end
|
592
|
-
|
593
|
-
router.path(:blossom, id: 23) # => "/blossoms/23" # Will route to Flowers::Show
|
594
|
-
```
|
595
|
-
|
596
|
-
#### Nested Resources
|
597
|
-
|
598
|
-
We can nest resource(s):
|
599
|
-
|
600
|
-
```ruby
|
601
|
-
router = Hanami::Router.new do
|
602
|
-
resources :users do
|
603
|
-
resource :avatar
|
604
|
-
resources :favorites
|
605
|
-
end
|
606
|
-
end
|
607
|
-
|
608
|
-
router.path(:user_avatar, user_id: 1) # => "/users/1/avatar"
|
609
|
-
router.path(:new_user_avatar, user_id: 1) # => "/users/1/avatar/new"
|
610
|
-
router.path(:edit_user_avatar, user_id: 1) # => "/users/1/avatar/edit"
|
611
|
-
|
612
|
-
router.path(:user_favorites, user_id: 1) # => "/users/1/favorites"
|
613
|
-
router.path(:user_favorite, user_id: 1, id: 2) # => "/users/1/favorites/2"
|
614
|
-
router.path(:new_user_favorites, user_id: 1) # => "/users/1/favorites/new"
|
615
|
-
router.path(:edit_user_favorites, user_id: 1, id: 2) # => "/users/1/favorites/2/edit"
|
616
|
-
```
|
617
|
-
|
618
228
|
### Body Parsers
|
619
229
|
|
620
230
|
Rack ignores request bodies unless they come from a form submission.
|
@@ -745,6 +355,6 @@ __Hanami::Router__ uses [Semantic Versioning 2.0.0](http://semver.org)
|
|
745
355
|
|
746
356
|
## Copyright
|
747
357
|
|
748
|
-
Copyright © 2014-
|
358
|
+
Copyright © 2014-2020 Luca Guidi – Released under MIT License
|
749
359
|
|
750
360
|
This project was formerly known as Lotus (`lotus-router`).
|