Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

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