josevalim-inherited_resources 0.6.3 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|