josevalim-inherited_resources 0.6.3 → 0.7.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/CHANGELOG +9 -0
- data/README +132 -105
- data/lib/inherited_resources/base.rb +15 -189
- data/lib/inherited_resources/base_helpers.rb +75 -39
- data/lib/inherited_resources/belongs_to_helpers.rb +62 -40
- data/lib/inherited_resources/class_methods.rb +268 -272
- data/lib/inherited_resources/dumb_responder.rb +7 -6
- data/lib/inherited_resources/has_scope_helpers.rb +65 -0
- data/lib/inherited_resources/polymorphic_helpers.rb +96 -5
- data/lib/inherited_resources/respond_to.rb +7 -7
- data/lib/inherited_resources/singleton_helpers.rb +48 -6
- data/lib/inherited_resources/url_helpers.rb +37 -36
- data/lib/inherited_resources.rb +4 -2
- data/test/base_helpers_test.rb +3 -92
- data/test/class_methods_test.rb +116 -75
- data/test/customized_belongs_to_test.rb +76 -0
- data/test/defaults_test.rb +2 -1
- data/test/flash_test.rb +83 -0
- data/test/has_scope_test.rb +171 -0
- data/test/test_helper.rb +4 -8
- data/test/url_helpers_test.rb +3 -3
- data/test/views/branches/edit.html.erb +1 -0
- data/test/views/branches/index.html.erb +1 -0
- data/test/views/branches/new.html.erb +1 -0
- data/test/views/branches/show.html.erb +1 -0
- data/test/views/pets/index.html.erb +1 -0
- data/test/views/pets/new.html.erb +1 -0
- data/test/views/pets/show.html.erb +1 -0
- data/test/views/trees/edit.html.erb +1 -0
- data/test/views/trees/index.html.erb +1 -0
- data/test/views/trees/new.html.erb +1 -0
- data/test/views/trees/show.html.erb +1 -0
- metadata +17 -2
data/CHANGELOG
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
# Version 0.7
|
2
|
+
|
3
|
+
* Added has_scope to controller (an interface for named_scopes).
|
4
|
+
* Added polymorphic_belongs_to, optional_belongs_to and singleton_belongs_to
|
5
|
+
as quick methods.
|
6
|
+
* Only load belongs_to, singleton and polymorphic helpers if they are actually
|
7
|
+
required. base_helpers, class_methods, dumb_responder and url_helpers are loaded
|
8
|
+
when you inherited from base for the first time.
|
9
|
+
|
1
10
|
# Version 0.6
|
2
11
|
|
3
12
|
* Ensure that the default template is not rendered if the default_template_format
|
data/README
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Inherited Resources
|
2
2
|
License: MIT
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.7.0
|
4
4
|
|
5
5
|
You can also read this README in pretty html at the GitHub project Wiki page:
|
6
6
|
|
@@ -36,10 +36,8 @@ If you want it as plugin, just do:
|
|
36
36
|
rspec-rails <= 1.1.12 known bug
|
37
37
|
-------------------------------
|
38
38
|
|
39
|
-
InheritedResources has a known bug with rspec-rails
|
40
|
-
|
41
|
-
InheritedResources ships with a patch. To apply it, just put the line below on
|
42
|
-
your spec_helper.rb after loading rspec and rspec-rails:
|
39
|
+
InheritedResources has a known bug with rspec-rails. Please upgrade your rspec
|
40
|
+
version or use the fix which ships with InheritedResources:
|
43
41
|
|
44
42
|
require 'inherited_resources/spec'
|
45
43
|
|
@@ -69,11 +67,9 @@ You can also specify them based per action:
|
|
69
67
|
respond_to :iphone, :except => [ :edit, :update ]
|
70
68
|
end
|
71
69
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
@project respond to :to_js. If it is true, it will render the result of :to_js,
|
76
|
-
otherwise it will render a 404.
|
70
|
+
For each request, it first checkes if the "controller/action.format" file is
|
71
|
+
available (for example "projects/create.xml") and if it's not, it checks if
|
72
|
+
the resource respond to :to_format (in this case, :to_xml). Otherwise returns 404.
|
77
73
|
|
78
74
|
Another option is to specify which actions the controller will inherit from
|
79
75
|
the InheritedResources::Base:
|
@@ -100,12 +96,9 @@ on index actions.
|
|
100
96
|
Overwriting defaults
|
101
97
|
--------------------
|
102
98
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
Some people usually have an AccountsController to deal with all account
|
107
|
-
management while the resource is an User. So you can overwrite the resource class,
|
108
|
-
collection name and instance name just doing:
|
99
|
+
Whenever you inherit from InheritedResources, several defaults are assumed.
|
100
|
+
For example you can have an AccountsController to account management while the
|
101
|
+
resource is an User:
|
109
102
|
|
110
103
|
class AccountsController < InheritedResources::Base
|
111
104
|
defaults :resource_class => User, :collection_name, 'users', :instance_name => 'user'
|
@@ -122,10 +115,13 @@ different route prefix, you can do the following:
|
|
122
115
|
defaults :route_prefix => 'admin'
|
123
116
|
end
|
124
117
|
|
125
|
-
Then your named routes will be: 'admin_people_url', 'admin_person_url'
|
118
|
+
Then your named routes will be: 'admin_people_url', 'admin_person_url' instead
|
119
|
+
of 'administrators_people_url' and 'administrators_person_url'.
|
126
120
|
|
127
|
-
|
128
|
-
|
121
|
+
If you want to customize how resources are retrieved you can overwrite
|
122
|
+
collection and resource methods. The first is called on index action and the
|
123
|
+
second on all other actions. Let's suppose you want to add pagination to your
|
124
|
+
projects collection:
|
129
125
|
|
130
126
|
class ProjectsController < InheritedResources::Base
|
131
127
|
protected
|
@@ -134,38 +130,14 @@ to add pagination to your projects collection:
|
|
134
130
|
end
|
135
131
|
end
|
136
132
|
|
137
|
-
|
138
|
-
|
139
|
-
class ProjectsController < InheritedResources::Base
|
140
|
-
protected
|
141
|
-
def collection
|
142
|
-
@projects ||= Project.paginate(params[:page]).all
|
143
|
-
end
|
144
|
-
end
|
133
|
+
The end_of_association_chain returns your resource after nesting all associations
|
134
|
+
and scopes (more about this below).
|
145
135
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
soon.
|
150
|
-
|
151
|
-
On the other hand, if you just added pretty urls for in your ProjectsController
|
152
|
-
(/projects/my-project-name), you can overwrite how projects are being found by:
|
153
|
-
|
154
|
-
class ProjectsController < InheritedResources::Base
|
155
|
-
protected
|
156
|
-
def resource
|
157
|
-
@project ||= end_of_association_chain.find_by_title!(params[:title])
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
And now since you is acquainted to end_of_association_chain let's meet its
|
162
|
-
twin brother: begin_of_association_chain.
|
163
|
-
|
164
|
-
It's mostly used when you want to create resources based on the @current_user.
|
165
|
-
In such cases, you don't have your @current_user in the url, but in the session.
|
166
|
-
|
167
|
-
This is usually when you have urls like "account/projects" and you have to do
|
136
|
+
InheritedResources also introduces another method called begin_of_association_chain.
|
137
|
+
It's mostly used when you want to create resources based on the @current_user and
|
138
|
+
you have urls like "account/projects". In such cases, so you have to do
|
168
139
|
@current_user.projects.find or @current_user.projects.build in your actions.
|
140
|
+
|
169
141
|
You can deal with it just doing:
|
170
142
|
|
171
143
|
class ProjectsController < InheritedResources::Base
|
@@ -192,9 +164,8 @@ root url instead of redirecting to projects url. You just have to do:
|
|
192
164
|
You are opening your action and giving the parent action a new behavior. No
|
193
165
|
tricks, no DSL, just Ruby.
|
194
166
|
|
195
|
-
On the other hand, I have to agree that calling super is
|
196
|
-
|
197
|
-
equivalent:
|
167
|
+
On the other hand, I have to agree that calling super is not very readable.
|
168
|
+
That's why all methods have aliases. So this is equivalent:
|
198
169
|
|
199
170
|
class ProjectsController < InheritedResources::Base
|
200
171
|
def destroy
|
@@ -204,7 +175,7 @@ equivalent:
|
|
204
175
|
end
|
205
176
|
end
|
206
177
|
|
207
|
-
Even more, since most of the times
|
178
|
+
Even more, since most of the times when you change a :create, :update or :destroy
|
208
179
|
action is because you want to to change to where it redirects, a shortcut is
|
209
180
|
provided. So you can do:
|
210
181
|
|
@@ -225,9 +196,8 @@ but you don't want to create a before filter for it:
|
|
225
196
|
end
|
226
197
|
end
|
227
198
|
|
228
|
-
|
229
|
-
@project, it will not
|
230
|
-
special. :)
|
199
|
+
Yes, that simple! The nice part is since you already set the instance variable
|
200
|
+
@project, it will not build a project again.
|
231
201
|
|
232
202
|
Before we finish this topic, we should talk about one more thing: "success/failure
|
233
203
|
blocks". Let's suppose that when we update our project, in case of failure, we
|
@@ -245,8 +215,7 @@ Our first attempt to do this would be:
|
|
245
215
|
end
|
246
216
|
end
|
247
217
|
|
248
|
-
Looks to verbose, right?
|
249
|
-
But this is Ruby and we can actually do:
|
218
|
+
Looks to verbose, right? We can actually do:
|
250
219
|
|
251
220
|
class ProjectsController < InheritedResources::Base
|
252
221
|
def update
|
@@ -271,11 +240,10 @@ order:
|
|
271
240
|
flash.controller_name.action_name.status
|
272
241
|
flash.actions.action_name.status
|
273
242
|
|
274
|
-
If none is available, a default message in english set.
|
275
|
-
projects
|
276
|
-
flash messages in the following order:
|
243
|
+
If none is available, a default message in english set. In a create action
|
244
|
+
on projects controller, it will search for:
|
277
245
|
|
278
|
-
flash.
|
246
|
+
flash.projects.create.status
|
279
247
|
flash.actions.create.status
|
280
248
|
|
281
249
|
The status can be :notice (when the object can be created, updated
|
@@ -291,34 +259,33 @@ is also localized and it means you can set:
|
|
291
259
|
notice: "Hooray! {{resource_name}} was successfully created!"
|
292
260
|
|
293
261
|
It will replace {{resource_name}} by the human name of the resource class,
|
294
|
-
which is "
|
262
|
+
which is "Project" in this case.
|
295
263
|
|
296
|
-
But sometimes, flash messages are not that simple.
|
297
|
-
|
298
|
-
updated. Well, that's easy also:
|
264
|
+
But sometimes, flash messages are not that simple. Sometimes you want to say
|
265
|
+
the title of the project while updating a project. Well, that's easy also:
|
299
266
|
|
300
267
|
flash:
|
301
|
-
|
268
|
+
projects:
|
302
269
|
update:
|
303
|
-
notice: "Hooray!
|
270
|
+
notice: "Hooray! The project "{{project_title}}" was updated!"
|
304
271
|
|
305
|
-
Since :
|
272
|
+
Since :project_title is not available for interpolation by default, you have
|
306
273
|
to overwrite interpolation_options.
|
307
274
|
|
308
275
|
def interpolation_options
|
309
|
-
{ :
|
276
|
+
{ :project_title => @project.title }
|
310
277
|
end
|
311
278
|
|
312
279
|
Then you will finally have:
|
313
280
|
|
314
|
-
|
281
|
+
"Hooray! The project "Plataforma" was updated!"
|
315
282
|
|
316
|
-
If your controller is namespaced, for example
|
283
|
+
If your controller is namespaced, for example Admin::ProjectsController, the
|
317
284
|
messages will be checked in the following order:
|
318
285
|
|
319
|
-
flash.
|
320
|
-
flash.
|
321
|
-
flash.
|
286
|
+
flash.admin.projects.create.notice
|
287
|
+
flash.admin.actions.create.notice
|
288
|
+
flash.projects.create.notice
|
322
289
|
flash.actions.create.notice
|
323
290
|
|
324
291
|
Belongs to
|
@@ -332,16 +299,15 @@ TasksController and do:
|
|
332
299
|
end
|
333
300
|
|
334
301
|
belongs_to accepts several options to be able to configure the association.
|
335
|
-
|
336
|
-
|
302
|
+
For example, if you want urls like /projects/:project_title/tasks, you can
|
303
|
+
customize how InheritedResources find your projects:
|
337
304
|
|
338
305
|
class TasksController < InheritedResources::Base
|
339
306
|
belongs_to :project, :finder => :find_by_title!, :param => :project_title
|
340
307
|
end
|
341
308
|
|
342
309
|
It also accepts :route_name, :parent_class and :instance_name as options.
|
343
|
-
|
344
|
-
for more customization. :)
|
310
|
+
Check the lib/inherited_resources/class_methods.rb for more.
|
345
311
|
|
346
312
|
Nested belongs to
|
347
313
|
-----------------
|
@@ -354,23 +320,95 @@ you have to for security reasons. So this is an example of how you can do it:
|
|
354
320
|
nested_belongs_to :project, :task
|
355
321
|
end
|
356
322
|
|
357
|
-
|
358
|
-
what is happening. You can also declare nested_belongs_to like this:
|
323
|
+
If you need to configure any of these belongs to, you can nested them using blocks:
|
359
324
|
|
360
325
|
class CommentsController < InheritedResources::Base
|
361
|
-
belongs_to :project do
|
326
|
+
belongs_to :project, :finder => :find_by_title!, :param => :project_title do
|
362
327
|
belongs_to :task
|
363
328
|
end
|
364
329
|
end
|
365
330
|
|
331
|
+
Warning: calling several belongs_to is the same as nesting them:
|
332
|
+
|
333
|
+
class CommentsConroller < InheritedResources::Base
|
334
|
+
belongs_to :project
|
335
|
+
belongs_to :task
|
336
|
+
end
|
337
|
+
|
338
|
+
In other words, the code above is the same as calling nested_belongs_to.
|
339
|
+
|
340
|
+
Has Scope
|
341
|
+
---------
|
342
|
+
|
343
|
+
InheritedResources besides belongs_to also speaks named_scope. Let's have a
|
344
|
+
break from projects and talk about graduations. Your model:
|
345
|
+
|
346
|
+
class Graduation < ActiveRecord::Base
|
347
|
+
named_scope :featured, :conditions => { :featured => true }
|
348
|
+
named_scope :by_degree, proc {|degree| { :conditions => { :degree => degree } } }
|
349
|
+
named_scope :limit, proc{|limit| :limit => limit.to_i }
|
350
|
+
end
|
351
|
+
|
352
|
+
Your controller:
|
353
|
+
|
354
|
+
class GraduationsController < InheritedResources::Base
|
355
|
+
has_scope :featured, :boolean => true, :only => :index
|
356
|
+
has_scope :by_degree
|
357
|
+
has_scope :limit, :default => 10
|
358
|
+
end
|
359
|
+
|
360
|
+
Then for each request:
|
361
|
+
|
362
|
+
/graduations
|
363
|
+
#=> acts like a normal request, but returning 10 resources
|
364
|
+
|
365
|
+
/graduations?featured=true
|
366
|
+
#=> calls the featured named scope and bring 10 featured graduations
|
367
|
+
|
368
|
+
/graduations?featured=true&by_degree=phd&limit=20
|
369
|
+
#=> brings 20 featured graduations with phd degree
|
370
|
+
|
371
|
+
You can also specify the target of the scope. Let's suppose that a Graduation
|
372
|
+
has many Students:
|
373
|
+
|
374
|
+
class StudentsController < InheritedResources::Base
|
375
|
+
belongs_to :graduation
|
376
|
+
|
377
|
+
has_scope :featured, :on => :graduation, :boolean => true, :only => :index
|
378
|
+
has_scope :by_degree, :on => :graduation, :only => :index
|
379
|
+
has_scope :limit, :on => :graduation, :default => 10
|
380
|
+
end
|
381
|
+
|
382
|
+
You can also do this inside the belongs to block:
|
383
|
+
|
384
|
+
class StudentsController < InheritedResources::Base
|
385
|
+
belongs_to :graduation do
|
386
|
+
has_scope :featured, :boolean => true, :only => :index
|
387
|
+
has_scope :by_degree, :only => :index
|
388
|
+
has_scope :limit, :default => 10
|
389
|
+
end
|
390
|
+
end
|
391
|
+
|
392
|
+
Or even better, you can load the scopes from another controller:
|
393
|
+
|
394
|
+
class StudentsController < InheritedResources::Base
|
395
|
+
belongs_to :graduation do
|
396
|
+
load_scopes_from GraduationsController
|
397
|
+
end
|
398
|
+
end
|
399
|
+
|
400
|
+
Another feature is that you can retrive the current scopes in use with
|
401
|
+
the method <tt>current_scopes</tt>, that returns a hash.
|
402
|
+
|
366
403
|
Polymorphic belongs to
|
367
404
|
----------------------
|
368
405
|
|
369
|
-
Now let's go
|
370
|
-
|
406
|
+
Now let's go back to Projects which can now have Files, Messages and Tasks, and
|
407
|
+
they are all commentable:
|
371
408
|
|
372
409
|
class CommentsController < InheritedResources::Base
|
373
410
|
belongs_to :task, :file, :message, :polymorphic => true
|
411
|
+
# polymorphic_belongs_to :task, :file, :message
|
374
412
|
end
|
375
413
|
|
376
414
|
You can even use it with nested resources:
|
@@ -388,29 +426,23 @@ When using polymorphic associations, you get some free helpers:
|
|
388
426
|
parent_class #=> Task
|
389
427
|
parent #=> @task
|
390
428
|
|
391
|
-
Polymorphic controller is another great idea by James Golick and he also uses
|
392
|
-
that on resource_controller.
|
393
|
-
|
394
429
|
Optional belongs to
|
395
430
|
-------------------
|
396
431
|
|
397
|
-
|
398
|
-
a
|
399
|
-
|
400
|
-
On the website, we can show all products, but also products scoped to
|
401
|
-
categories, brands, users, etc. In this case case, the association is optional,
|
402
|
-
and we deal with it in the following way:
|
432
|
+
Later you decide to create a view to show all comments, independing they belong
|
433
|
+
to a task, file or message. You canm reuse your previous controller just doing:
|
403
434
|
|
404
|
-
class
|
405
|
-
belongs_to :
|
435
|
+
class ProjectsController < InheritedResources::Base
|
436
|
+
belongs_to :task, :file, :message, :optional => true
|
437
|
+
# optional_belongs_to :task, :file, :message
|
406
438
|
end
|
407
439
|
|
408
440
|
This will handle all those urls properly:
|
409
441
|
|
410
|
-
/
|
411
|
-
/
|
412
|
-
/
|
413
|
-
/
|
442
|
+
/comment/1
|
443
|
+
/tasks/2/comment/5
|
444
|
+
/files/10/comment/3
|
445
|
+
/messages/13/comment/11
|
414
446
|
|
415
447
|
This is treated as a special type of polymorphic associations, thus all helpers
|
416
448
|
are available. As you expect, when no parent is found, the helpers return:
|
@@ -432,6 +464,7 @@ option.
|
|
432
464
|
|
433
465
|
class ManagersController < InheritedResources::Base
|
434
466
|
belongs_to :project, :singleton => true
|
467
|
+
# singleton_belongs_to :project
|
435
468
|
end
|
436
469
|
|
437
470
|
It will deal with everything again and hide the action :index from you.
|
@@ -475,12 +508,6 @@ Another nice thing is that those urls are not guessed during runtime. They are
|
|
475
508
|
all created when your application is loaded (except for polymorphic
|
476
509
|
associations, that relies on Rails polymorphic_url).
|
477
510
|
|
478
|
-
What's next
|
479
|
-
-----------
|
480
|
-
|
481
|
-
I'm working on generators and some nice things to speed up and make easier
|
482
|
-
your controllers tests with mocking and stubs. :)
|
483
|
-
|
484
511
|
Bugs and Feedback
|
485
512
|
-----------------
|
486
513
|
|
@@ -1,196 +1,22 @@
|
|
1
|
-
#
|
2
|
-
#
|
3
|
-
# To use InheritedResources you have to inherit from InheritedResources::Base
|
4
|
-
# class. This class have all Rails REST actions defined (index, show, new, edit
|
5
|
-
# update, create and destroy). The following definition is the same as a Rails
|
6
|
-
# scaffolded controller:
|
7
|
-
#
|
8
|
-
# class ProjectController < InheritedResources::Base
|
9
|
-
# end
|
10
|
-
#
|
11
|
-
# All actions are defined, check it!
|
12
|
-
#
|
13
|
-
# The next step is to define which mime types this controller provides:
|
14
|
-
#
|
15
|
-
# class ProjectController < InheritedResources::Base
|
16
|
-
# respond_to :html, :xml, :json
|
17
|
-
# end
|
18
|
-
#
|
19
|
-
# You just said that this controller will respond to :html, :xml and :json. You
|
20
|
-
# can also specify it based on actions:
|
21
|
-
#
|
22
|
-
# class ProjectController < InheritedResources::Base
|
23
|
-
# respond_to :html, :xml, :json
|
24
|
-
# respond_to :js, :only => :create
|
25
|
-
# respond_to :csv, :except => [ :destroy ]
|
26
|
-
# end
|
27
|
-
#
|
28
|
-
# How it works is simple. Let's suppose you have a json request on the action
|
29
|
-
# show. It will first try to render "projects/show.json.something". If it can't
|
30
|
-
# be found, it will call :to_json in the resource, which in this case is
|
31
|
-
# @project.
|
32
|
-
#
|
33
|
-
# If the resource @project doesn't respond to :to_json, we will render a 404
|
34
|
-
# Not Found.
|
35
|
-
#
|
36
|
-
# If you don't want to inherit all actions from InheritedResources::Base, call
|
37
|
-
# actions method with the actions you want to inherit:
|
38
|
-
#
|
39
|
-
# class ProjectController < InheritedResources::Base
|
40
|
-
# actions :index, :show, :new, :create, :edit, :update
|
41
|
-
# end
|
42
|
-
#
|
43
|
-
# Or:
|
44
|
-
#
|
45
|
-
# class ProjectController < InheritedResources::Base
|
46
|
-
# actions :all, :except => :destroy
|
47
|
-
# end
|
48
|
-
#
|
49
|
-
# = Extending the default behaviour
|
50
|
-
#
|
51
|
-
# Let's suppose that after destroying a project you want to redirect to your
|
52
|
-
# root url instead of redirecting to projects url. You just have to do:
|
53
|
-
#
|
54
|
-
# class ProjectController < InheritedResources::Base
|
55
|
-
# def destroy
|
56
|
-
# super do |format|
|
57
|
-
# format.html { redirect_to root_url }
|
58
|
-
# end
|
59
|
-
# end
|
60
|
-
# end
|
61
|
-
#
|
62
|
-
# super? Yes, we agree that calling super is the right thing but it does not
|
63
|
-
# look nice. That's why all methods have aliases. So this is equivalent:
|
64
|
-
#
|
65
|
-
# class ProjectController < InheritedResources::Base
|
66
|
-
# def destroy
|
67
|
-
# destroy! do |format|
|
68
|
-
# format.html { redirect_to root_url }
|
69
|
-
# end
|
70
|
-
# end
|
71
|
-
# end
|
72
|
-
#
|
73
|
-
# Even more, since most of the times that you change a :create, :update or :destroy
|
74
|
-
# action is because you want to to change to where it redirects, a shortcut is
|
75
|
-
# provided. So you can do:
|
76
|
-
#
|
77
|
-
# class ProjectsController < InheritedResources::Base
|
78
|
-
# def destroy
|
79
|
-
# destroy!(root_url)
|
80
|
-
# end
|
81
|
-
# end
|
82
|
-
#
|
83
|
-
# Since this is actually Ruby (and not a new DSL), if you want to do something
|
84
|
-
# before creating the project that is to small to deserve a before_filter, you
|
85
|
-
# could simply do:
|
86
|
-
#
|
87
|
-
# class ProjectController < InheritedResources::Base
|
88
|
-
# def create
|
89
|
-
# # do something different!
|
90
|
-
# create!
|
91
|
-
# end
|
92
|
-
# end
|
93
|
-
#
|
94
|
-
# And as instance variables are shared you can do more nice things.
|
95
|
-
# Let's suppose you want to create a project based on the current user:
|
96
|
-
#
|
97
|
-
# class ProjectController < InheritedResources::Base
|
98
|
-
# def create
|
99
|
-
# @project = @current_user.projects.build(params[:project])
|
100
|
-
# create!
|
101
|
-
# end
|
102
|
-
# end
|
103
|
-
#
|
104
|
-
# When you call create! the instance variable @project is already defined,
|
105
|
-
# so the method won't instanciate it again.
|
106
|
-
#
|
107
|
-
# The great thing is that we are not using blocks or nothing in special. We are
|
108
|
-
# just inheriting and calling the parent (super). You can extend even more
|
109
|
-
# without using blocks, please check helpers.rb for more info.
|
110
|
-
#
|
111
|
-
# = Flash and I18n
|
112
|
-
#
|
113
|
-
# Flash messages are changed through I18n API. If you have a ProjectsController,
|
114
|
-
# when a resource is updated with success, it will search for messages in the
|
115
|
-
# following order:
|
116
|
-
#
|
117
|
-
# 'flash.projects.update.notice'
|
118
|
-
# 'flash.actions.update.notice'
|
119
|
-
#
|
120
|
-
# If none of them are not available, it will show the default message:
|
121
|
-
#
|
122
|
-
# Project was successfully updated.
|
123
|
-
#
|
124
|
-
# The message will be set into flash[:notice].
|
125
|
-
# Messages can be interpolated, so you can do the following in your I18n files:
|
126
|
-
#
|
127
|
-
# flash:
|
128
|
-
# actions:
|
129
|
-
# update:
|
130
|
-
# notice: "Hooray! {{resource_name}} was updated with success!"
|
131
|
-
#
|
132
|
-
# It will replace {{resource_name}} by Project.human_name, which is also localized
|
133
|
-
# (check http://rails-i18n.org/wiki/pages/i18n-rails-guide for more info).
|
134
|
-
#
|
135
|
-
# But sometimes, flash messages are not that simple. You might want to say the
|
136
|
-
# the name of the project when it's updated. Well, that's easy also:
|
137
|
-
#
|
138
|
-
# flash:
|
139
|
-
# projects:
|
140
|
-
# update:
|
141
|
-
# notice: "Dear manager, {{project_name}} was successfully updated!"
|
142
|
-
#
|
143
|
-
# Since :project_name is not available for interpolation by default, you
|
144
|
-
# have to overwrite interpolation_options method on your controller.
|
145
|
-
#
|
146
|
-
# def interpolation_options
|
147
|
-
# { :project_name => @project.quoted_name }
|
148
|
-
# end
|
149
|
-
#
|
150
|
-
# Then you will finally have:
|
151
|
-
#
|
152
|
-
# 'Dear manager, "Make Rails Scale" was successfully updated!'
|
153
|
-
#
|
154
|
-
# Success messages appear on :create, :update and :destroy actions. Failure
|
155
|
-
# messages appear only on :create and :update.
|
156
|
-
#
|
157
|
-
# = Changing assumptions
|
158
|
-
#
|
159
|
-
# When you inherit from InheritedResources::Base, we make some assumptions on
|
160
|
-
# what is your resource_class, instance_name and collection_name.
|
161
|
-
#
|
162
|
-
# You can change those values by calling the class method defaults:
|
163
|
-
#
|
164
|
-
# class PeopleController < InheritedResources::Base
|
165
|
-
# defaults :resource_class => User, :instance_name => 'user', :collection_name => 'users'
|
166
|
-
# end
|
167
|
-
#
|
168
|
-
# Namespaced controllers work out of the box, but if you need to specify a
|
169
|
-
# different route prefix, you can do the following:
|
170
|
-
#
|
171
|
-
# class Administrators::PeopleController < InheritedResources::Base
|
172
|
-
# defaults :route_prefix => 'admin'
|
173
|
-
# end
|
174
|
-
#
|
175
|
-
# Then your named routes will be: 'admin_people_url', 'admin_person_url' and
|
176
|
-
# so on.
|
177
|
-
#
|
178
|
-
# Further customizations can be done replacing some methods. Check
|
179
|
-
# base_helpers.rb file for more information.
|
180
|
-
|
181
|
-
# Let's require all needed files here. We are still on time to eager load
|
182
|
-
# everything on multithreaded environments.
|
1
|
+
# Whenever Base is required, we eager load the base files. belongs_to, polymorphic
|
2
|
+
# and singleton helpers are loaded on demand.
|
183
3
|
require File.dirname(__FILE__) + '/base_helpers.rb'
|
184
|
-
require File.dirname(__FILE__) + '/belongs_to_helpers.rb'
|
185
4
|
require File.dirname(__FILE__) + '/class_methods.rb'
|
186
5
|
require File.dirname(__FILE__) + '/dumb_responder.rb'
|
187
|
-
require File.dirname(__FILE__) + '/polymorphic_helpers.rb'
|
188
|
-
require File.dirname(__FILE__) + '/singleton_helpers.rb'
|
189
6
|
require File.dirname(__FILE__) + '/url_helpers.rb'
|
190
7
|
|
191
8
|
module InheritedResources
|
192
|
-
RESOURCES_ACTIONS = [ :index, :show, :new, :edit, :create, :update, :destroy ] unless self.const_defined?
|
193
|
-
|
9
|
+
RESOURCES_ACTIONS = [ :index, :show, :new, :edit, :create, :update, :destroy ] unless self.const_defined?(:RESOURCES_ACTIONS)
|
10
|
+
|
11
|
+
# = Base
|
12
|
+
#
|
13
|
+
# This is the base class that holds all actions. If you see the code for each
|
14
|
+
# action, they are quite similar to Rails default scaffold.
|
15
|
+
#
|
16
|
+
# To change your base behavior, you can overwrite your actions and call super,
|
17
|
+
# call <tt>default</tt> class method, call <<tt>actions</tt> class method
|
18
|
+
# or overwrite some helpers in the base_helpers.rb file.
|
19
|
+
#
|
194
20
|
class Base < ::ApplicationController
|
195
21
|
unloadable
|
196
22
|
|
@@ -199,9 +25,9 @@ module InheritedResources
|
|
199
25
|
|
200
26
|
helper_method :collection_url, :collection_path, :resource_url, :resource_path,
|
201
27
|
:new_resource_url, :new_resource_path, :edit_resource_url, :edit_resource_path,
|
202
|
-
:resource, :collection, :resource_class
|
28
|
+
:resource, :collection, :resource_class
|
203
29
|
|
204
|
-
def self.inherited(base)
|
30
|
+
def self.inherited(base) #:nodoc:
|
205
31
|
base.class_eval do
|
206
32
|
# Make all resources actions public
|
207
33
|
public *RESOURCES_ACTIONS
|