sinatra-trails 0.0.6 → 0.0.7
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.
- data/{README.rdoc → README.md} +29 -48
- data/lib/sinatra/trails.rb +10 -44
- data/lib/sinatra/trails/version.rb +1 -1
- data/spec/route_generation_spec.rb +9 -91
- metadata +15 -15
data/{README.rdoc → README.md}
RENAMED
@@ -1,20 +1,16 @@
|
|
1
|
-
sinatra-trails
|
2
|
-
--------------
|
1
|
+
# sinatra-trails
|
3
2
|
|
4
|
-
Is a very thin Rails inspired route naming DSL for using with Sinatra apps.
|
3
|
+
Is a very thin Rails inspired route naming DSL for using with Sinatra apps.
|
5
4
|
It doesn't monkeypatch or overrides any Sinatra::Base methods
|
6
5
|
It provides helpers for generating routes for resources and single resource, namespaces and named routes.
|
7
6
|
|
8
|
-
Instalation
|
9
|
-
----------
|
7
|
+
# Instalation
|
10
8
|
|
11
9
|
$ [sudo] gem install sinatra-trails
|
12
10
|
|
13
|
-
Usage
|
14
|
-
----
|
11
|
+
# Usage
|
15
12
|
|
16
|
-
Basic
|
17
|
-
=====
|
13
|
+
## Basic
|
18
14
|
|
19
15
|
Named routes are generated with map, not passing :to option sets the path to be the same as the name:
|
20
16
|
|
@@ -23,9 +19,9 @@ Named routes are generated with map, not passing :to option sets the path to be
|
|
23
19
|
class MyApp < Sinatra::Base
|
24
20
|
register Sinatra::Trails
|
25
21
|
|
26
|
-
map :dashboard
|
27
|
-
map :home, :to => '/'
|
28
|
-
map :post, :to => '/posts/:id'
|
22
|
+
map :dashboard
|
23
|
+
map :home, :to => '/'
|
24
|
+
map :post, :to => '/posts/:id'
|
29
25
|
end
|
30
26
|
|
31
27
|
MyApp.print_routes
|
@@ -65,10 +61,9 @@ All defined routes will be available in the views and action blocks:
|
|
65
61
|
end
|
66
62
|
|
67
63
|
|
68
|
-
Namespaces
|
69
|
-
==========
|
64
|
+
## Namespaces
|
70
65
|
|
71
|
-
|
66
|
+
Passing a symbol namespaces both the path and the route name:
|
72
67
|
|
73
68
|
namespace :admin do
|
74
69
|
map(:dashboard)
|
@@ -93,8 +88,7 @@ Passing nil to namespace only sets a context:
|
|
93
88
|
route_for(:dashboard) # => '/dashboard'
|
94
89
|
|
95
90
|
|
96
|
-
Resources
|
97
|
-
=========
|
91
|
+
## Resources
|
98
92
|
|
99
93
|
Restful routes for plural resources can be generated as follows, inside the resource
|
100
94
|
definition block a route can be accessed by its name as a method call or using the path_for method:
|
@@ -134,10 +128,21 @@ definition block a route can be accessed by its name as a method call or using t
|
|
134
128
|
delete user do
|
135
129
|
...
|
136
130
|
end
|
131
|
+
|
132
|
+
# generates new route with name :aprove_user
|
133
|
+
# GET /users/:id/aprove
|
134
|
+
get member(:aprove) do
|
135
|
+
...
|
136
|
+
end
|
137
|
+
|
138
|
+
# generates new route with name :aproved_users
|
139
|
+
# GET /users/aproved
|
140
|
+
get collection(:aproved) do
|
141
|
+
...
|
142
|
+
end
|
137
143
|
end
|
138
144
|
|
139
|
-
|
140
|
-
in this case `get(new_user)` must be defined before `get(user)`
|
145
|
+
Route definition order for sinatra has precedence, in this case `get(new_user)` must be defined before `get(user)`
|
141
146
|
|
142
147
|
As with previous examples routes can be defined beforehand:
|
143
148
|
|
@@ -148,10 +153,9 @@ As with previous examples routes can be defined beforehand:
|
|
148
153
|
end
|
149
154
|
|
150
155
|
|
151
|
-
Nested Resources
|
152
|
-
================
|
156
|
+
## Nested Resources
|
153
157
|
|
154
|
-
Resources can be nested in a similar way as with Rails
|
158
|
+
Resources can be nested in a similar way as with Rails:
|
155
159
|
|
156
160
|
resources :users do
|
157
161
|
...
|
@@ -195,25 +199,6 @@ And for actions that don't need to load the parent resource the route generation
|
|
195
199
|
# comment => /comments/:id
|
196
200
|
# edit_comment => /comments/:id/edit
|
197
201
|
|
198
|
-
There's an alternative way of generating routes for nested resources:
|
199
|
-
|
200
|
-
resources :users => {:posts => :comments}, :shallow => true do
|
201
|
-
...
|
202
|
-
end
|
203
|
-
print_routes
|
204
|
-
# users => /users
|
205
|
-
# new_user => /users/new
|
206
|
-
# user => /users/:id
|
207
|
-
# edit_user => /users/:id/edit
|
208
|
-
# user_posts => /users/:user_id/posts
|
209
|
-
# new_user_post => /users/:user_id/posts/new
|
210
|
-
# post => /posts/:id
|
211
|
-
# edit_post => /posts/:id/edit
|
212
|
-
# post_comments => /posts/:post_id/comments
|
213
|
-
# new_post_comment => /posts/:post_id/comments/new
|
214
|
-
# comment => /comments/:id
|
215
|
-
# edit_comment => /comments/:id/edit
|
216
|
-
|
217
202
|
Some keys to the params hash are added when routes are defined using sinatra-trails:
|
218
203
|
|
219
204
|
params[:resource] # the name of the resource in REST actions
|
@@ -221,8 +206,7 @@ Some keys to the params hash are added when routes are defined using sinatra-tra
|
|
221
206
|
params[:namespace] # the name of the current namespace
|
222
207
|
|
223
208
|
|
224
|
-
Singleton Resource
|
225
|
-
=================
|
209
|
+
## Singleton Resource
|
226
210
|
|
227
211
|
Same principles apply for singleton resource:
|
228
212
|
|
@@ -233,8 +217,7 @@ Same principles apply for singleton resource:
|
|
233
217
|
# edit_user => /user/edit
|
234
218
|
|
235
219
|
|
236
|
-
Before and After Filters
|
237
|
-
========================
|
220
|
+
## Before and After Filters
|
238
221
|
|
239
222
|
Defining a filter within a context (namespace, resources, resource) without passing any path will execute that filter for
|
240
223
|
all actions defined in that context:
|
@@ -273,9 +256,7 @@ A symbol can be passed to the filter definition and it will be lazily evaluated
|
|
273
256
|
end
|
274
257
|
end
|
275
258
|
|
276
|
-
|
277
|
-
Accessing Routes from Outside the App
|
278
|
-
=====================================
|
259
|
+
## Accessing Routes from Outside the App
|
279
260
|
|
280
261
|
On registering Sinatra::Trails a dynamic module for the Sinatra app is created and it is assigned to the constant `Routes`
|
281
262
|
including that module in another class gives that class access to the app's paths, a single class can access paths for
|
data/lib/sinatra/trails.rb
CHANGED
@@ -115,12 +115,12 @@ module Sinatra
|
|
115
115
|
@routes += Scope.new(@sinatra_app, path, [*ancestors, self]).generate_routes!(&block)
|
116
116
|
end
|
117
117
|
|
118
|
-
def resource
|
119
|
-
restful_routes Resource,
|
118
|
+
def resource name, opts = {}, &block
|
119
|
+
restful_routes Resource, name, opts, &block
|
120
120
|
end
|
121
121
|
|
122
|
-
def resources
|
123
|
-
restful_routes Resources,
|
122
|
+
def resources name, opts = {}, &block
|
123
|
+
restful_routes Resources, name, opts, &block
|
124
124
|
end
|
125
125
|
|
126
126
|
def before *args, &block
|
@@ -151,50 +151,16 @@ module Sinatra
|
|
151
151
|
|
152
152
|
private
|
153
153
|
def method_missing name, *args, &block
|
154
|
-
|
155
|
-
|
156
|
-
return route unless block_given?
|
157
|
-
@routes = @routes | route.scope.generate_routes!(&block)
|
154
|
+
if @sinatra_app.respond_to? name
|
155
|
+
@sinatra_app.send name, *args, &block
|
158
156
|
else
|
159
|
-
super
|
157
|
+
route_for(name) or super
|
160
158
|
end
|
161
159
|
end
|
162
160
|
|
163
|
-
def restful_routes builder,
|
164
|
-
|
165
|
-
|
166
|
-
hash.delete_if { |key, val| opts[key] = val if !(Symbol === val || Enumerable === val) }
|
167
|
-
|
168
|
-
nested = []
|
169
|
-
mash = Proc.new do |hash, acc|
|
170
|
-
hash.map do |key, val|
|
171
|
-
case val
|
172
|
-
when Hash
|
173
|
-
[*acc, key, *mash.call(val, key).flatten]
|
174
|
-
when Array
|
175
|
-
nested += val.map{ |r| [*acc, key, r] } and next
|
176
|
-
else
|
177
|
-
[key, val]
|
178
|
-
end
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
hash = (mash.call(hash) + nested).compact.map do |array|
|
183
|
-
array.reverse.inject(Proc.new{}) do |proc, name|
|
184
|
-
Proc.new{ send(builder == Resource ? :resource : :resources, name, opts, &proc) }
|
185
|
-
end.call
|
186
|
-
end
|
187
|
-
|
188
|
-
make = lambda do |name|
|
189
|
-
builder.new(@sinatra_app, name, [*ancestors, self], (@opts || {}).merge(opts))
|
190
|
-
end
|
191
|
-
|
192
|
-
if names.size == 1 && hash.empty?
|
193
|
-
@routes += make.call(names.first).generate_routes!(&block)
|
194
|
-
else
|
195
|
-
names.each { |name| @routes += make.call(name).generate_routes! }
|
196
|
-
instance_eval &block if block_given?
|
197
|
-
end
|
161
|
+
def restful_routes builder, name, opts, &block
|
162
|
+
scope = builder.new(@sinatra_app, name, [*ancestors, self], (@opts || {}).merge(opts))
|
163
|
+
@routes += scope.generate_routes!(&block)
|
198
164
|
end
|
199
165
|
end
|
200
166
|
|
@@ -154,8 +154,8 @@ describe 'trails' do
|
|
154
154
|
|
155
155
|
describe 'basic' do
|
156
156
|
before :all do
|
157
|
-
app.resources :users
|
158
|
-
|
157
|
+
app.resources :users
|
158
|
+
app.resources :posts
|
159
159
|
end
|
160
160
|
it_should_behave_like 'generates routes for users'
|
161
161
|
it_should_behave_like 'generates routes for posts'
|
@@ -248,74 +248,14 @@ describe 'trails' do
|
|
248
248
|
it_should_behave_like 'generates routes for users'
|
249
249
|
it_should_behave_like 'generates routes for shallow user posts'
|
250
250
|
end
|
251
|
-
|
252
|
-
describe 'hash nested' do
|
253
|
-
before :all do
|
254
|
-
app.resources :users => :posts
|
255
|
-
end
|
256
|
-
it_should_behave_like 'generates routes for users'
|
257
|
-
it_should_behave_like 'generates routes for nested user posts'
|
258
|
-
end
|
259
|
-
|
260
|
-
describe 'hash nested with block' do
|
261
|
-
before :all do
|
262
|
-
app.resources :users => :posts do
|
263
|
-
map :flag
|
264
|
-
end
|
265
|
-
end
|
266
|
-
it_should_behave_like 'generates routes for users'
|
267
|
-
it_should_behave_like 'generates routes for nested user posts'
|
268
|
-
it { app.route_for(:flag).should == '/flag' }
|
269
|
-
end
|
270
|
-
|
271
|
-
describe 'nested shallow with hash' do
|
272
|
-
before :all do
|
273
|
-
app.resources :users => :posts, :shallow => true
|
274
|
-
end
|
275
|
-
it_should_behave_like 'generates routes for users'
|
276
|
-
it_should_behave_like 'generates routes for shallow user posts'
|
277
|
-
end
|
278
|
-
|
279
|
-
describe 'deep nested with hash' do
|
280
|
-
before :all do
|
281
|
-
app.resources :users => {:posts => :comments}
|
282
|
-
end
|
283
|
-
it_should_behave_like 'generates routes for users'
|
284
|
-
it_should_behave_like 'generates routes for nested user posts'
|
285
|
-
describe 'exageration' do
|
286
|
-
it { app.route_for(:user_post_comments).should == '/users/:user_id/posts/:post_id/comments' }
|
287
|
-
it { app.route_for(:new_user_post_comment).should == '/users/:user_id/posts/:post_id/comments/new' }
|
288
|
-
it { app.route_for(:user_post_comment).should == '/users/:user_id/posts/:post_id/comments/:id' }
|
289
|
-
it { app.route_for(:edit_user_post_comment).should == '/users/:user_id/posts/:post_id/comments/:id/edit' }
|
290
|
-
end
|
291
|
-
end
|
292
|
-
|
293
|
-
describe 'deep nested shallow with hash' do
|
294
|
-
before :all do
|
295
|
-
app.resources :users => {:posts => :comments}, :shallow => true
|
296
|
-
end
|
297
|
-
it_should_behave_like 'generates routes for users'
|
298
|
-
it_should_behave_like 'generates routes for shallow user posts'
|
299
|
-
it { app.route_for(:post_comments).should == '/posts/:post_id/comments' }
|
300
|
-
it { app.route_for(:new_post_comment).should == '/posts/:post_id/comments/new' }
|
301
|
-
it { app.route_for(:comment).should == '/comments/:id' }
|
302
|
-
it { app.route_for(:edit_comment).should == '/comments/:id/edit' }
|
303
|
-
end
|
304
|
-
|
305
|
-
describe 'nested with array' do
|
306
|
-
before :all do
|
307
|
-
app.resources :users => [:posts, :comments]
|
308
|
-
end
|
309
|
-
it { app.route_for(:users).should == '/users' }
|
310
|
-
it { app.route_for(:user_comments).should == '/users/:user_id/comments' }
|
311
|
-
it { app.route_for(:user_posts).should == '/users/:user_id/posts' }
|
312
|
-
end
|
313
251
|
end
|
314
252
|
|
315
253
|
describe 'single resource' do
|
316
254
|
describe 'basic' do
|
317
255
|
before :all do
|
318
|
-
app.resource :user
|
256
|
+
app.resource :user do
|
257
|
+
resource :profile
|
258
|
+
end
|
319
259
|
end
|
320
260
|
it { app.route_for(:user).should == '/user' }
|
321
261
|
it { app.route_for(:new_user).should == '/user/new' }
|
@@ -389,30 +329,6 @@ describe 'trails' do
|
|
389
329
|
end
|
390
330
|
end
|
391
331
|
|
392
|
-
describe 'using route as scope' do
|
393
|
-
before :all do
|
394
|
-
app.resources(:users => :posts, :shallow => true) do
|
395
|
-
users do
|
396
|
-
get(member(:aprove)) { path_for(:aprove_user, params[:id]) }
|
397
|
-
end
|
398
|
-
|
399
|
-
user_posts do
|
400
|
-
get(member(:aprove)) { path_for(:aprove_post, params[:id]) }
|
401
|
-
end
|
402
|
-
end
|
403
|
-
end
|
404
|
-
|
405
|
-
it 'should define action for users member' do
|
406
|
-
get '/users/1/aprove'
|
407
|
-
last_response.body.should == '/users/1/aprove'
|
408
|
-
end
|
409
|
-
|
410
|
-
it 'should define action for user_posts member' do
|
411
|
-
get '/posts/1/aprove'
|
412
|
-
last_response.body.should == '/posts/1/aprove'
|
413
|
-
end
|
414
|
-
end
|
415
|
-
|
416
332
|
describe 'before without args' do
|
417
333
|
before :all do
|
418
334
|
app.instance_eval do
|
@@ -533,9 +449,11 @@ describe 'trails' do
|
|
533
449
|
|
534
450
|
describe 'having access to resource name' do
|
535
451
|
before :all do
|
536
|
-
app.resources
|
452
|
+
app.resources :users do
|
537
453
|
get(users){ params[:resource].to_s }
|
538
|
-
|
454
|
+
resources :posts do
|
455
|
+
get(user_posts){ params[:resource].to_s }
|
456
|
+
end
|
539
457
|
end
|
540
458
|
end
|
541
459
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sinatra-trails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,12 +9,12 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-11-
|
12
|
+
date: 2011-11-30 00:00:00.000000000 -06:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: sinatra
|
17
|
-
requirement: &
|
17
|
+
requirement: &70214353481380 !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
20
|
- - ! '>='
|
@@ -22,10 +22,10 @@ dependencies:
|
|
22
22
|
version: '0'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
|
-
version_requirements: *
|
25
|
+
version_requirements: *70214353481380
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: i18n
|
28
|
-
requirement: &
|
28
|
+
requirement: &70214353480840 !ruby/object:Gem::Requirement
|
29
29
|
none: false
|
30
30
|
requirements:
|
31
31
|
- - ! '>='
|
@@ -33,10 +33,10 @@ dependencies:
|
|
33
33
|
version: '0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
|
-
version_requirements: *
|
36
|
+
version_requirements: *70214353480840
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
38
|
name: activesupport
|
39
|
-
requirement: &
|
39
|
+
requirement: &70214353479960 !ruby/object:Gem::Requirement
|
40
40
|
none: false
|
41
41
|
requirements:
|
42
42
|
- - ! '>='
|
@@ -44,10 +44,10 @@ dependencies:
|
|
44
44
|
version: '3.0'
|
45
45
|
type: :runtime
|
46
46
|
prerelease: false
|
47
|
-
version_requirements: *
|
47
|
+
version_requirements: *70214353479960
|
48
48
|
- !ruby/object:Gem::Dependency
|
49
49
|
name: rake
|
50
|
-
requirement: &
|
50
|
+
requirement: &70214353479280 !ruby/object:Gem::Requirement
|
51
51
|
none: false
|
52
52
|
requirements:
|
53
53
|
- - ! '>='
|
@@ -55,10 +55,10 @@ dependencies:
|
|
55
55
|
version: '0'
|
56
56
|
type: :development
|
57
57
|
prerelease: false
|
58
|
-
version_requirements: *
|
58
|
+
version_requirements: *70214353479280
|
59
59
|
- !ruby/object:Gem::Dependency
|
60
60
|
name: rspec
|
61
|
-
requirement: &
|
61
|
+
requirement: &70214353474980 !ruby/object:Gem::Requirement
|
62
62
|
none: false
|
63
63
|
requirements:
|
64
64
|
- - ! '>='
|
@@ -66,10 +66,10 @@ dependencies:
|
|
66
66
|
version: '0'
|
67
67
|
type: :development
|
68
68
|
prerelease: false
|
69
|
-
version_requirements: *
|
69
|
+
version_requirements: *70214353474980
|
70
70
|
- !ruby/object:Gem::Dependency
|
71
71
|
name: rack-test
|
72
|
-
requirement: &
|
72
|
+
requirement: &70214353471960 !ruby/object:Gem::Requirement
|
73
73
|
none: false
|
74
74
|
requirements:
|
75
75
|
- - ! '>='
|
@@ -77,7 +77,7 @@ dependencies:
|
|
77
77
|
version: '0'
|
78
78
|
type: :development
|
79
79
|
prerelease: false
|
80
|
-
version_requirements: *
|
80
|
+
version_requirements: *70214353471960
|
81
81
|
description: A named routes Sinatra DSL inspired by Rails routing
|
82
82
|
email:
|
83
83
|
- macarui@gmail.com
|
@@ -88,7 +88,7 @@ files:
|
|
88
88
|
- .gitignore
|
89
89
|
- .rspec
|
90
90
|
- Gemfile
|
91
|
-
- README.
|
91
|
+
- README.md
|
92
92
|
- Rakefile
|
93
93
|
- lib/sinatra/trails.rb
|
94
94
|
- lib/sinatra/trails/version.rb
|