josevalim-inherited_resources 0.8.5 → 0.9.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.
- data/README +231 -220
- data/Rakefile +2 -0
- data/VERSION +1 -1
- data/lib/inherited_resources.rb +7 -2
- data/lib/inherited_resources/actions.rb +17 -39
- data/lib/inherited_resources/base.rb +3 -0
- data/lib/inherited_resources/base_helpers.rb +25 -35
- data/lib/inherited_resources/class_methods.rb +7 -6
- data/lib/inherited_resources/legacy/respond_to.rb +151 -0
- data/lib/inherited_resources/legacy/responder.rb +181 -0
- data/lib/inherited_resources/polymorphic_helpers.rb +3 -4
- data/test/aliases_test.rb +23 -18
- data/test/base_helpers_test.rb +7 -0
- data/test/base_test.rb +5 -5
- data/test/flash_test.rb +10 -5
- data/test/redirect_to_test.rb +0 -26
- data/test/respond_to_test.rb +29 -188
- data/test/test_helper.rb +4 -1
- metadata +4 -3
- data/lib/inherited_resources/respond_to.rb +0 -339
data/README
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Inherited Resources
|
2
2
|
License: MIT
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.9.0
|
4
4
|
|
5
5
|
You can also read this README in pretty html at the GitHub project Wiki page:
|
6
6
|
|
@@ -26,28 +26,20 @@ Installation
|
|
26
26
|
Install Inherited Resources is very easy. It is stored in GitHub, so just run
|
27
27
|
the following:
|
28
28
|
|
29
|
-
|
30
|
-
|
29
|
+
gem sources -a http://gems.github.com
|
30
|
+
sudo gem install josevalim-inherited_resources
|
31
31
|
|
32
32
|
If you want it as plugin, just do:
|
33
33
|
|
34
|
-
|
35
|
-
|
36
|
-
rspec-rails <= 1.1.12 known bug
|
37
|
-
-------------------------------
|
38
|
-
|
39
|
-
InheritedResources has a known bug with rspec-rails. Please upgrade your rspec
|
40
|
-
version or use the fix which ships with InheritedResources:
|
41
|
-
|
42
|
-
require 'inherited_resources/spec'
|
34
|
+
script/plugin install git://github.com/josevalim/inherited_resources.git
|
43
35
|
|
44
36
|
Basic Usage
|
45
37
|
-----------
|
46
38
|
|
47
39
|
To use Inherited Resources you just have to inherit (duh) it:
|
48
40
|
|
49
|
-
|
50
|
-
|
41
|
+
class ProjectsController < InheritedResources::Base
|
42
|
+
end
|
51
43
|
|
52
44
|
And all actions are defined and working, check it! Your projects collection
|
53
45
|
(in the index action) is still available in the instance variable @projects
|
@@ -55,17 +47,17 @@ and your project resource (all other actions) is available as @ project.
|
|
55
47
|
|
56
48
|
The next step is to define which mime types this controller provides:
|
57
49
|
|
58
|
-
|
59
|
-
|
60
|
-
|
50
|
+
class ProjectsController < InheritedResources::Base
|
51
|
+
respond_to :html, :xml, :json
|
52
|
+
end
|
61
53
|
|
62
54
|
You can also specify them based per action:
|
63
55
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
56
|
+
class ProjectsController < InheritedResources::Base
|
57
|
+
respond_to :html, :xml, :json
|
58
|
+
respond_to :js, :only => :create
|
59
|
+
respond_to :iphone, :except => [ :edit, :update ]
|
60
|
+
end
|
69
61
|
|
70
62
|
For each request, it first checkes if the "controller/action.format" file is
|
71
63
|
available (for example "projects/create.xml") and if it's not, it checks if
|
@@ -74,31 +66,31 @@ the resource respond to :to_format (in this case, :to_xml). Otherwise returns 40
|
|
74
66
|
Another option is to specify which actions the controller will inherit from
|
75
67
|
the InheritedResources::Base:
|
76
68
|
|
77
|
-
|
78
|
-
|
79
|
-
|
69
|
+
class ProjectsController < InheritedResources::Base
|
70
|
+
actions :index, :show, :new, :create
|
71
|
+
end
|
80
72
|
|
81
73
|
Or:
|
82
74
|
|
83
|
-
|
84
|
-
|
85
|
-
|
75
|
+
class ProjectsController < InheritedResources::Base
|
76
|
+
actions :all, :except => [ :edit, :update, :destroy ]
|
77
|
+
end
|
86
78
|
|
87
79
|
In your views, you will get the following helpers:
|
88
80
|
|
89
|
-
|
90
|
-
|
91
|
-
|
81
|
+
resource #=> @project
|
82
|
+
collection #=> @projects
|
83
|
+
resource_class #=> Project
|
92
84
|
|
93
85
|
As you might expect, collection (@projects instance variable) is only available
|
94
86
|
on index actions.
|
95
87
|
|
96
88
|
If for some reason you cannot inherit from InheritedResources::Base, you can
|
97
|
-
call inherit_resources
|
89
|
+
call inherit_resources in your controller class scope:
|
98
90
|
|
99
|
-
|
100
|
-
|
101
|
-
|
91
|
+
class AccountsController < ApplicationController
|
92
|
+
inherit_resources
|
93
|
+
end
|
102
94
|
|
103
95
|
Overwriting defaults
|
104
96
|
--------------------
|
@@ -107,9 +99,9 @@ Whenever you inherit from InheritedResources, several defaults are assumed.
|
|
107
99
|
For example you can have an AccountsController to account management while the
|
108
100
|
resource is an User:
|
109
101
|
|
110
|
-
|
111
|
-
|
112
|
-
|
102
|
+
class AccountsController < InheritedResources::Base
|
103
|
+
defaults :resource_class => User, :collection_name => 'users', :instance_name => 'user'
|
104
|
+
end
|
113
105
|
|
114
106
|
In the case above, in your views you will have @users and @user variables, but
|
115
107
|
the routes used will still be accounts_url and account_url. If you plan also to
|
@@ -118,9 +110,9 @@ change the routes, you can use :route_collection_name and :route_instance_name.
|
|
118
110
|
Namespaced controllers work out of the box, but if you need to specify a
|
119
111
|
different route prefix, you can do the following:
|
120
112
|
|
121
|
-
|
122
|
-
|
123
|
-
|
113
|
+
class Administrators::PeopleController < InheritedResources::Base
|
114
|
+
defaults :route_prefix => 'admin'
|
115
|
+
end
|
124
116
|
|
125
117
|
Then your named routes will be: 'admin_people_url', 'admin_person_url' instead
|
126
118
|
of 'administrators_people_url' and 'administrators_person_url'.
|
@@ -130,12 +122,12 @@ collection and resource methods. The first is called on index action and the
|
|
130
122
|
second on all other actions. Let's suppose you want to add pagination to your
|
131
123
|
projects collection:
|
132
124
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
125
|
+
class ProjectsController < InheritedResources::Base
|
126
|
+
protected
|
127
|
+
def collection
|
128
|
+
@projects ||= end_of_association_chain.paginate(params[:page]).all
|
129
|
+
end
|
130
|
+
end
|
139
131
|
|
140
132
|
The end_of_association_chain returns your resource after nesting all associations
|
141
133
|
and scopes (more about this below).
|
@@ -147,12 +139,12 @@ you have urls like "account/projects". In such cases, you have to do
|
|
147
139
|
|
148
140
|
You can deal with it just doing:
|
149
141
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
142
|
+
class ProjectsController < InheritedResources::Base
|
143
|
+
protected
|
144
|
+
def begin_of_association_chain
|
145
|
+
@current_user
|
146
|
+
end
|
147
|
+
end
|
156
148
|
|
157
149
|
Overwriting actions
|
158
150
|
-------------------
|
@@ -160,48 +152,46 @@ Overwriting actions
|
|
160
152
|
Let's suppose that after destroying a project you want to redirect to your
|
161
153
|
root url instead of redirecting to projects url. You just have to do:
|
162
154
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
You are opening your action and giving the parent action a new behavior.
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
end
|
183
|
-
end
|
155
|
+
class ProjectsController < InheritedResources::Base
|
156
|
+
def destroy
|
157
|
+
super do |format|
|
158
|
+
format.html { redirect_to root_url }
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
You are opening your action and giving the parent action a new behavior. On
|
164
|
+
the other hand, I have to agree that calling super is not very readable. That's
|
165
|
+
why all methods have aliases. So this is equivalent:
|
166
|
+
|
167
|
+
class ProjectsController < InheritedResources::Base
|
168
|
+
def destroy
|
169
|
+
destroy! do |format|
|
170
|
+
format.html { redirect_to root_url }
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
184
174
|
|
185
175
|
Even more, since most of the times when you change a create, update or destroy
|
186
176
|
action is because you want to to change to where it redirects, a shortcut is
|
187
177
|
provided. So you can do:
|
188
178
|
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
179
|
+
class ProjectsController < InheritedResources::Base
|
180
|
+
def destroy
|
181
|
+
destroy!{ root_url }
|
182
|
+
end
|
183
|
+
end
|
194
184
|
|
195
185
|
Now let's suppose that before create a project you have to do something special
|
196
186
|
but you don't want to create a before filter for it:
|
197
187
|
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
188
|
+
class ProjectsController < InheritedResources::Base
|
189
|
+
def create
|
190
|
+
@project = Project.new(params[:project])
|
191
|
+
@project.something_special!
|
192
|
+
create!
|
193
|
+
end
|
194
|
+
end
|
205
195
|
|
206
196
|
Yes, that simple! The nice part is since you already set the instance variable
|
207
197
|
@project, it will not build a project again.
|
@@ -212,25 +202,25 @@ want to redirect to the project url instead of re-rendering the edit template.
|
|
212
202
|
|
213
203
|
Our first attempt to do this would be:
|
214
204
|
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
205
|
+
class ProjectsController < InheritedResources::Base
|
206
|
+
def update
|
207
|
+
update! do |format|
|
208
|
+
unless @project.errors.empty? # failure
|
209
|
+
format.html { redirect_to project_url(@project) }
|
210
|
+
end
|
211
|
+
end
|
222
212
|
end
|
223
|
-
|
213
|
+
end
|
224
214
|
|
225
215
|
Looks to verbose, right? We can actually do:
|
226
216
|
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
217
|
+
class ProjectsController < InheritedResources::Base
|
218
|
+
def update
|
219
|
+
update! do |success, failure|
|
220
|
+
failure.html { redirect_to project_url(@project) }
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
234
224
|
|
235
225
|
Much better! So explaining everything: when you give a block which expects one
|
236
226
|
argument it will be executed in both scenarios: success and failure. But If you
|
@@ -238,20 +228,39 @@ give a block that expects two arguments, the first will be executed only in
|
|
238
228
|
success scenarios and the second in failure scenarios. You keep everything
|
239
229
|
clean and organized inside the same action.
|
240
230
|
|
231
|
+
Some DSL
|
232
|
+
--------
|
233
|
+
|
234
|
+
For those DSL lovers, InheritedResources won't leave you alone. You can overwrite
|
235
|
+
your success/failure blocks straight from your class binding. For it, you just
|
236
|
+
need to add a DSL block to your application controller:
|
237
|
+
|
238
|
+
class ApplicationController < ActionController::Base
|
239
|
+
include InheritedResources::DSL
|
240
|
+
end
|
241
|
+
|
242
|
+
And then you can rewrite the last example as:
|
243
|
+
|
244
|
+
class ProjectsController < InheritedResources::Base
|
245
|
+
update! do |success, failure|
|
246
|
+
failure.html { redirect_to project_url(@project) }
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
241
250
|
Flash messages and I18n
|
242
251
|
-----------------------
|
243
252
|
|
244
253
|
Flash messages are powered by I18n api. It checks for messages in the following
|
245
254
|
order:
|
246
255
|
|
247
|
-
|
248
|
-
|
256
|
+
flash.controller_name.action_name.status
|
257
|
+
flash.actions.action_name.status
|
249
258
|
|
250
259
|
If none is available, a default message in english set. In a create action
|
251
260
|
on projects controller, it will search for:
|
252
261
|
|
253
|
-
|
254
|
-
|
262
|
+
flash.projects.create.status
|
263
|
+
flash.actions.create.status
|
255
264
|
|
256
265
|
The status can be :notice (when the object can be created, updated
|
257
266
|
or destroyed with success) or :error (when the objecy cannot be created
|
@@ -260,10 +269,10 @@ or updated).
|
|
260
269
|
Those messages are interpolated by using the resource class human name, which
|
261
270
|
is also localized and it means you can set:
|
262
271
|
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
272
|
+
flash:
|
273
|
+
actions:
|
274
|
+
create:
|
275
|
+
notice: "Hooray! {{resource_name}} was successfully created!"
|
267
276
|
|
268
277
|
It will replace {{resource_name}} by the human name of the resource class,
|
269
278
|
which is "Project" in this case.
|
@@ -271,36 +280,36 @@ which is "Project" in this case.
|
|
271
280
|
But sometimes, flash messages are not that simple. Sometimes you want to say
|
272
281
|
the title of the project while updating a project. Well, that's easy also:
|
273
282
|
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
283
|
+
flash:
|
284
|
+
projects:
|
285
|
+
update:
|
286
|
+
notice: "Hooray! The project "{{project_title}}" was updated!"
|
278
287
|
|
279
288
|
Since :project_title is not available for interpolation by default, you have
|
280
289
|
to overwrite interpolation_options.
|
281
290
|
|
282
|
-
|
283
|
-
|
284
|
-
|
291
|
+
def interpolation_options
|
292
|
+
{ :project_title => @project.title }
|
293
|
+
end
|
285
294
|
|
286
295
|
Then you will finally have:
|
287
296
|
|
288
|
-
|
297
|
+
"Hooray! The project "Plataforma" was updated!"
|
289
298
|
|
290
299
|
By default, resource name is capitalized. If you want to make it lower case, you
|
291
300
|
can add to your application controller:
|
292
301
|
|
293
|
-
|
294
|
-
|
295
|
-
|
302
|
+
def interpolation_options
|
303
|
+
{ :resource_name => resource_class.human_name.downcase }
|
304
|
+
end
|
296
305
|
|
297
306
|
Finally, if your controller is namespaced, for example Admin::ProjectsController,
|
298
307
|
the messages will be checked in the following order:
|
299
308
|
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
309
|
+
flash.admin.projects.create.notice
|
310
|
+
flash.admin.actions.create.notice
|
311
|
+
flash.projects.create.notice
|
312
|
+
flash.actions.create.notice
|
304
313
|
|
305
314
|
Has Scope
|
306
315
|
---------
|
@@ -308,40 +317,40 @@ Has Scope
|
|
308
317
|
InheritedResources tries to integrate nicely with your model. In order to do so,
|
309
318
|
it also is named_scope fluent. Let's suppose our Project model with the scopes:
|
310
319
|
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
320
|
+
class Project < ActiveRecord::Base
|
321
|
+
named_scope :featured, :conditions => { :featured => true }
|
322
|
+
named_scope :by_methodology, proc {|methodology| { :conditions => { :methodology => methodology } } }
|
323
|
+
named_scope :limit, proc{|limit| :limit => limit.to_i }
|
324
|
+
end
|
316
325
|
|
317
326
|
Your controller:
|
318
327
|
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
328
|
+
class ProjectsController < InheritedResources::Base
|
329
|
+
has_scope :featured, :boolean => true, :only => :index
|
330
|
+
has_scope :by_methodology
|
331
|
+
has_scope :limit, :default => 10
|
332
|
+
end
|
324
333
|
|
325
334
|
Then for each request:
|
326
335
|
|
327
|
-
|
328
|
-
|
336
|
+
/projects
|
337
|
+
#=> acts like a normal request, but returning 10 projects
|
329
338
|
|
330
|
-
|
331
|
-
|
339
|
+
/projects?featured=true
|
340
|
+
#=> calls the featured named scope and bring 10 featured projects
|
332
341
|
|
333
|
-
|
334
|
-
|
342
|
+
/projects?featured=true&by_methodology=agile&limit=20
|
343
|
+
#=> brings 20 featured projects with methodology agile
|
335
344
|
|
336
345
|
You can retrieve the current scopes in use with :current_scopes method.
|
337
346
|
In the last case, it would return:
|
338
347
|
|
339
|
-
|
348
|
+
{ :featured => "true", :by_methodology => "agile", :limit => "20" }
|
340
349
|
|
341
350
|
Finally, let's suppose you store on the session how many projects the user sees
|
342
351
|
per page. In such cases, you can give a proc as default value:
|
343
352
|
|
344
|
-
|
353
|
+
has_scope :limit, :default => proc{|c| c.session[:limit] || 10 }
|
345
354
|
|
346
355
|
Belongs to
|
347
356
|
----------
|
@@ -349,17 +358,17 @@ Belongs to
|
|
349
358
|
Finally, our Projects are going to get some Tasks. Then you create a
|
350
359
|
TasksController and do:
|
351
360
|
|
352
|
-
|
353
|
-
|
354
|
-
|
361
|
+
class TasksController < InheritedResources::Base
|
362
|
+
belongs_to :project
|
363
|
+
end
|
355
364
|
|
356
365
|
belongs_to accepts several options to be able to configure the association.
|
357
366
|
For example, if you want urls like /projects/:project_title/tasks, you can
|
358
367
|
customize how InheritedResources find your projects:
|
359
368
|
|
360
|
-
|
361
|
-
|
362
|
-
|
369
|
+
class TasksController < InheritedResources::Base
|
370
|
+
belongs_to :project, :finder => :find_by_title!, :param => :project_title
|
371
|
+
end
|
363
372
|
|
364
373
|
It also accepts :route_name, :parent_class and :instance_name as options.
|
365
374
|
Check the lib/inherited_resources/class_methods.rb for more.
|
@@ -371,24 +380,24 @@ Now, our Tasks get some Comments and you need to nest even deeper. Good
|
|
371
380
|
practices says that you should never nest more than two resources, but sometimes
|
372
381
|
you have to for security reasons. So this is an example of how you can do it:
|
373
382
|
|
374
|
-
|
375
|
-
|
376
|
-
|
383
|
+
class CommentsController < InheritedResources::Base
|
384
|
+
nested_belongs_to :project, :task
|
385
|
+
end
|
377
386
|
|
378
|
-
If you need to configure any of these belongs to, you can
|
387
|
+
If you need to configure any of these belongs to, you can nest them using blocks:
|
379
388
|
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
389
|
+
class CommentsController < InheritedResources::Base
|
390
|
+
belongs_to :project, :finder => :find_by_title!, :param => :project_title do
|
391
|
+
belongs_to :task
|
392
|
+
end
|
393
|
+
end
|
385
394
|
|
386
395
|
Warning: calling several belongs_to is the same as nesting them:
|
387
396
|
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
397
|
+
class CommentsConroller < InheritedResources::Base
|
398
|
+
belongs_to :project
|
399
|
+
belongs_to :task
|
400
|
+
end
|
392
401
|
|
393
402
|
In other words, the code above is the same as calling nested_belongs_to.
|
394
403
|
|
@@ -399,31 +408,31 @@ We can go even further. Let's suppose our Projects can now have Files, Messages
|
|
399
408
|
and Tasks, and they are all commentable. In this case, the best solution is to
|
400
409
|
use polymorphism:
|
401
410
|
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
411
|
+
class CommentsController < InheritedResources::Base
|
412
|
+
belongs_to :task, :file, :message, :polymorphic => true
|
413
|
+
# polymorphic_belongs_to :task, :file, :message
|
414
|
+
end
|
406
415
|
|
407
416
|
You can even use it with nested resources:
|
408
417
|
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
418
|
+
class CommentsController < InheritedResources::Base
|
419
|
+
belongs_to :project do
|
420
|
+
belongs_to :task, :file, :message, :polymorphic => true
|
421
|
+
end
|
422
|
+
end
|
414
423
|
|
415
424
|
The url in such cases can be:
|
416
425
|
|
417
|
-
|
418
|
-
|
419
|
-
|
426
|
+
/project/1/task/13/comments
|
427
|
+
/project/1/file/11/comments
|
428
|
+
/project/1/message/9/comments
|
420
429
|
|
421
430
|
When using polymorphic associations, you get some free helpers:
|
422
431
|
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
432
|
+
parent? #=> true
|
433
|
+
parent_type #=> :task
|
434
|
+
parent_class #=> Task
|
435
|
+
parent #=> @task
|
427
436
|
|
428
437
|
Optional belongs to
|
429
438
|
-------------------
|
@@ -431,25 +440,25 @@ Optional belongs to
|
|
431
440
|
Later you decide to create a view to show all comments, independent if they belong
|
432
441
|
to a task, file or message. You can reuse your polymorphic controller just doing:
|
433
442
|
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
443
|
+
class ProjectsController < InheritedResources::Base
|
444
|
+
belongs_to :task, :file, :message, :optional => true
|
445
|
+
# optional_belongs_to :task, :file, :message
|
446
|
+
end
|
438
447
|
|
439
448
|
This will handle all those urls properly:
|
440
449
|
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
450
|
+
/comment/1
|
451
|
+
/tasks/2/comment/5
|
452
|
+
/files/10/comment/3
|
453
|
+
/messages/13/comment/11
|
445
454
|
|
446
455
|
This is treated as a special type of polymorphic associations, thus all helpers
|
447
456
|
are available. As you expect, when no parent is found, the helpers return:
|
448
457
|
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
458
|
+
parent? #=> false
|
459
|
+
parent_type #=> nil
|
460
|
+
parent_class #=> nil
|
461
|
+
parent #=> nil
|
453
462
|
|
454
463
|
Singletons
|
455
464
|
----------
|
@@ -461,10 +470,10 @@ has_one (or resource) in your routes.
|
|
461
470
|
To declare an association as singleton, you just have to give the :singleton
|
462
471
|
option.
|
463
472
|
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
473
|
+
class ManagersController < InheritedResources::Base
|
474
|
+
belongs_to :project, :singleton => true
|
475
|
+
# singleton_belongs_to :project
|
476
|
+
end
|
468
477
|
|
469
478
|
It will deal with everything again and hide the action :index from you.
|
470
479
|
|
@@ -474,34 +483,36 @@ URL Helpers
|
|
474
483
|
When you use InheritedResources it creates some URL helpers.
|
475
484
|
And they handle everything for you. :)
|
476
485
|
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
486
|
+
# /posts/1/comments
|
487
|
+
resource_url # => /posts/1/comments/#{@comment.to_param}
|
488
|
+
resource_url(comment) # => /posts/1/comments/#{comment.to_param}
|
489
|
+
new_resource_url # => /posts/1/comments/new
|
490
|
+
edit_resource_url # => /posts/1/comments/#{@comment.to_param}/edit
|
491
|
+
edit_resource_url(comment) #=> /posts/1/comments/#{comment.to_param}/edit
|
492
|
+
collection_url # => /posts/1/comments
|
493
|
+
|
494
|
+
# /projects/1/tasks
|
495
|
+
resource_url # => /projects/1/tasks/#{@task.to_param}
|
496
|
+
resource_url(task) # => /projects/1/tasks/#{task.to_param}
|
497
|
+
new_resource_url # => /projects/1/tasks/new
|
498
|
+
edit_resource_url # => /projects/1/tasks/#{@task.to_param}/edit
|
499
|
+
edit_resource_url(task) # => /projects/1/tasks/#{task.to_param}/edit
|
500
|
+
collection_url # => /projects/1/tasks
|
501
|
+
|
502
|
+
# /users
|
503
|
+
resource_url # => /users/#{@user.to_param}
|
504
|
+
resource_url(user) # => /users/#{user.to_param}
|
505
|
+
new_resource_url # => /users/new
|
506
|
+
edit_resource_url # => /users/#{@user.to_param}/edit
|
507
|
+
edit_resource_url(user) # => /users/#{user.to_param}/edit
|
508
|
+
collection_url # => /users
|
500
509
|
|
501
510
|
Those urls helpers also accepts a hash as options, just as in named routes.
|
502
511
|
|
503
|
-
|
504
|
-
|
512
|
+
# /projects/1/tasks
|
513
|
+
collection_url(:page => 1, :limit => 10) #=> /projects/1/tasks?page=1&limit=10
|
514
|
+
|
515
|
+
In polymorphic cases, you can also give the parent as parameter to collection_url.
|
505
516
|
|
506
517
|
Another nice thing is that those urls are not guessed during runtime. They are
|
507
518
|
all created when your application is loaded (except for polymorphic
|
@@ -510,8 +521,8 @@ associations, that relies on Rails polymorphic_url).
|
|
510
521
|
Bugs and Feedback
|
511
522
|
-----------------
|
512
523
|
|
513
|
-
If you discover any bugs, please send an e-mail to jose.valim@
|
524
|
+
If you discover any bugs, please send an e-mail to jose.valim@plataformatec.com.br
|
514
525
|
If you just want to give some positive feedback or drop a line, that's fine too!
|
515
526
|
|
516
527
|
Copyright (c) 2009 José Valim
|
517
|
-
http://
|
528
|
+
http://blog.plataformatec.com.br/
|