josevalim-inherited_resources 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. data/CHANGELOG +4 -0
  2. data/MIT-LICENSE +21 -0
  3. data/README +362 -0
  4. data/Rakefile +19 -0
  5. data/init.rb +1 -0
  6. data/lib/inherited_resources.rb +4 -0
  7. data/lib/inherited_resources/base.rb +272 -0
  8. data/lib/inherited_resources/base_helpers.rb +199 -0
  9. data/lib/inherited_resources/belongs_to.rb +227 -0
  10. data/lib/inherited_resources/belongs_to_helpers.rb +89 -0
  11. data/lib/inherited_resources/class_methods.rb +155 -0
  12. data/lib/inherited_resources/polymorphic_helpers.rb +19 -0
  13. data/lib/inherited_resources/respond_to.rb +324 -0
  14. data/lib/inherited_resources/singleton_helpers.rb +53 -0
  15. data/lib/inherited_resources/url_helpers.rb +147 -0
  16. data/test/aliases_test.rb +71 -0
  17. data/test/base_helpers_test.rb +130 -0
  18. data/test/base_test.rb +219 -0
  19. data/test/belongs_to_base_test.rb +268 -0
  20. data/test/belongs_to_test.rb +109 -0
  21. data/test/class_methods_test.rb +73 -0
  22. data/test/fixtures/en.yml +9 -0
  23. data/test/nested_belongs_to_test.rb +138 -0
  24. data/test/polymorphic_base_test.rb +282 -0
  25. data/test/respond_to_test.rb +282 -0
  26. data/test/singleton_base_test.rb +226 -0
  27. data/test/test_helper.rb +37 -0
  28. data/test/url_helpers_test.rb +284 -0
  29. data/test/views/cities/edit.html.erb +1 -0
  30. data/test/views/cities/index.html.erb +1 -0
  31. data/test/views/cities/new.html.erb +1 -0
  32. data/test/views/cities/show.html.erb +1 -0
  33. data/test/views/comments/edit.html.erb +1 -0
  34. data/test/views/comments/index.html.erb +1 -0
  35. data/test/views/comments/new.html.erb +1 -0
  36. data/test/views/comments/show.html.erb +1 -0
  37. data/test/views/employees/edit.html.erb +1 -0
  38. data/test/views/employees/index.html.erb +1 -0
  39. data/test/views/employees/new.html.erb +1 -0
  40. data/test/views/employees/show.html.erb +1 -0
  41. data/test/views/managers/edit.html.erb +1 -0
  42. data/test/views/managers/new.html.erb +1 -0
  43. data/test/views/managers/show.html.erb +1 -0
  44. data/test/views/pets/edit.html.erb +1 -0
  45. data/test/views/professors/edit.html.erb +1 -0
  46. data/test/views/professors/index.html.erb +1 -0
  47. data/test/views/professors/new.html.erb +1 -0
  48. data/test/views/professors/show.html.erb +1 -0
  49. data/test/views/projects/index.html.erb +1 -0
  50. data/test/views/projects/respond_to_with_resource.html.erb +1 -0
  51. data/test/views/students/edit.html.erb +1 -0
  52. data/test/views/students/new.html.erb +1 -0
  53. data/test/views/users/edit.html.erb +1 -0
  54. data/test/views/users/index.html.erb +1 -0
  55. data/test/views/users/new.html.erb +1 -0
  56. data/test/views/users/show.html.erb +1 -0
  57. metadata +108 -0
data/CHANGELOG ADDED
@@ -0,0 +1,4 @@
1
+ Version 0.1
2
+
3
+ * Initial release. Support to I18n, singleton controllers, polymorphic
4
+ controllers, belongs_to, nested_belongs_to and url helpers.
data/MIT-LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2006 Coda Hale
2
+ Copyright (c) 2008 José Valim (jose.valim at gmail dot com)
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,362 @@
1
+ Inherited Resources
2
+ License: MIT
3
+ Version: 0.1
4
+
5
+ You can also read this README in pretty html at the GitHub project Wiki page:
6
+
7
+ http://github.com/josevalim/inherited_resources/wikis/home
8
+
9
+ Description
10
+ -----------
11
+
12
+ Inherited Resources speeds up development by making your controllers inherit
13
+ all restful actions so you just have to focus on what is important. It makes
14
+ your controllers more powerful and cleaner at the same time.
15
+
16
+ keywords: resources, controller, singleton, belongs_to, polymorphic and I18n
17
+
18
+ Installation
19
+ ------------
20
+
21
+ Install Inherited Resources is very easy. It is stored in GitHub, so just run
22
+ the following:
23
+
24
+ gem sources -a http://gems.github.com
25
+ sudo gem install josevalim-inherited_resources
26
+
27
+ If you want it as plugin, just do:
28
+
29
+ script/plugin install git://github.com/josevalim/inherited_resources.git
30
+
31
+ Basic Usage
32
+ -----------
33
+
34
+ To use Inherited Resources you just have to inherit (duh) it:
35
+
36
+ class ProjectsController < ResourceController::Base
37
+ end
38
+
39
+ And all actions are defined and working, check it! Your projects collection
40
+ (in the index action) is still available in the instance variable @projects
41
+ and your project resource (all other actions) is available as @ project.
42
+
43
+ The next step is to define which mime types this controller provides:
44
+
45
+ class ProjectsController < InheritedResources::Base
46
+ respond_to :html, :xml, :json
47
+ end
48
+
49
+ You can also specify them based per action:
50
+
51
+ class ProjectsController < InheritedResources::Base
52
+ respond_to :html, :xml, :json
53
+ respond_to :js, :only => :create
54
+ respond_to :iphone, :except => [ :edit, :update ]
55
+ end
56
+
57
+ Let's take a request on create with :rjs as example of how it works. After the
58
+ action is processed, it will check if the view "projects/create.js.rjs" exist.
59
+ If it does exist, it will render it, otherwise it will check if the resource
60
+ @project respond to :to_js. If it is true, it will render the result of :to_js,
61
+ otherwise it will render a 404.
62
+
63
+ Another option is to specify which actions the controller will inherit from
64
+ the InheritedResources::Base:
65
+
66
+ class ProjectsController < InheritedResources::Base
67
+ actions :index, :show, :new, :create
68
+ end
69
+
70
+ Or:
71
+
72
+ class ProjectsController < InheritedResources::Base
73
+ actions :all, :except => [ :edit, :update, :destroy ]
74
+ end
75
+
76
+ Overwriting defaults
77
+ --------------------
78
+
79
+ Now that you learned the default behavior and basic configuration, let's see
80
+ how to extend it.
81
+
82
+ Assuming that you have a PeopleController, but the resource is actually called
83
+ User, you could overwrite the resource name, collection name and instance name
84
+ just doing:
85
+
86
+ class PeopleController < InheritedResources::Base
87
+ defaults :resource_class => User, :collection_name => 'users', :instance_name => 'user'
88
+ end
89
+
90
+ Further extensions is done by overwriting two methods. Let's suppose you want
91
+ to add pagination to your projects collection:
92
+
93
+ class ProjectsController < InheritedResources::Base
94
+ protected
95
+ def collection
96
+ @projects ||= end_of_association_chain.paginate(params[:page]).all
97
+ end
98
+ end
99
+
100
+ In this case you could just have done:
101
+
102
+ class ProjectsController < InheritedResources::Base
103
+ protected
104
+ def collection
105
+ @projects ||= Project.paginate(params[:page]).all
106
+ end
107
+ end
108
+
109
+ But you should get used if end_of_association_chain. When you have nested
110
+ resources it's very handy and it will deal with all nesting stuff. It was first
111
+ introduced in resource_controller by Jamis Golick and we will talk more about it
112
+ soon.
113
+
114
+ On the other hand, if you just added pretty urls for in your ProjectsController
115
+ (/projects/my-project-name), you can overwrite how projects are being found by:
116
+
117
+ class ProjectsController < InheritedResources::Base
118
+ protected
119
+ def resource
120
+ @project ||= end_of_association_chain.find_by_title!(params[:title])
121
+ end
122
+ end
123
+
124
+ And now since you is acquainted to end_of_association_chain let's meet its
125
+ twin brother: begin_of_association_chain.
126
+
127
+ It's mostly used when you want to create resources based on the @current_user.
128
+ In such cases, you don't have your @current_user in the url, but in the session.
129
+
130
+ So if you have to do: @current_user.projects.find or @current_user.projects.build
131
+ you can deal with both just doing:
132
+
133
+ class ProjectsController < InheritedResources::Base
134
+ protected
135
+ def begin_of_association_chain
136
+ @current_user
137
+ end
138
+ end
139
+
140
+ Overwriting actions
141
+ -------------------
142
+
143
+ Let's suppose that after destroying a project you want to redirect to your
144
+ root url instead of redirecting to projects url. You just have to do:
145
+
146
+ class ProjectsController < InheritedResources::Base
147
+ def destroy
148
+ super do |format|
149
+ format.html { redirect_to root_url }
150
+ end
151
+ end
152
+ end
153
+
154
+ You are opening your action and giving the parent action a new behavior. No
155
+ tricks, no DSL, just Ruby.
156
+
157
+ On the other hand, I have to agree that calling super is the right thing but
158
+ is not very readable. That's why all methods have aliases. So this is
159
+ equivalent:
160
+
161
+ class ProjectsController < InheritedResources::Base
162
+ def destroy
163
+ destroy! do |format|
164
+ format.html { redirect_to projects_url }
165
+ end
166
+ end
167
+ end
168
+
169
+ Now let's suppose that before create a project you have to do something special
170
+ but you don't want to create a before filter for it:
171
+
172
+ class ProjectsController < InheritedResources::Base
173
+ def create
174
+ @project = Project.new(params[:project])
175
+ @project.something_special!
176
+ create!
177
+ end end
178
+
179
+ Yeap, that simple! The nice part is since you already set the instance variable
180
+ @project, it will not do it again and overwrite your @project with something
181
+ special. :)
182
+
183
+ Flash messages and I18n
184
+ -----------------------
185
+
186
+ Flash messages are powered by I18n api. It checks for messages in the following
187
+ order:
188
+
189
+ flash.controller_name.action_name.status
190
+ flash.actions.action_name.status
191
+
192
+ If none is available, a default message in english set. Let's have a break from
193
+ projects and talk about CarsController. So in a create action, it will check for
194
+ flash messages in the following order:
195
+
196
+ flash.cars.create.status
197
+ flash.actions.create.status
198
+
199
+ The status can be :notice (when the object can be created, updated
200
+ or destroyed with success) or :error (when the objecy cannot be created
201
+ or updated).
202
+
203
+ Those messages are interpolated by using the resource class human name, which
204
+ is also localized and it means you can set:
205
+
206
+ flash:
207
+ actions:
208
+ create:
209
+ notice: "Hooray! {{resource}} was successfully created!"
210
+
211
+ It will replace {{resource}} for Car properly.
212
+
213
+ But sometimes, flash messages are not that simple. Going back
214
+ to cars example, you might want to say the brand of the car when it's
215
+ updated. Well, that's easy also:
216
+
217
+ flash:
218
+ cars:
219
+ update:
220
+ notice: "Hooray! You just tuned your {{car_brand}}!"
221
+
222
+ Since :car_name is not available for interpolation by default, you have
223
+ to overwrite interpolation_options.
224
+
225
+ def interpolation_options
226
+ { :car_brand => @car.brand }
227
+ end
228
+
229
+ Then you will finally have:
230
+
231
+ 'Hooray! You just tuned your Aston Martin!'
232
+
233
+ Belongs to
234
+ ----------
235
+
236
+ Finally, our Projects are going to get some Tasks. Then you create a
237
+ TasksController and do:
238
+
239
+ class TasksController < InheritedResources::Base
240
+ belongs_to :project
241
+ end
242
+
243
+ belongs_to accepts several options to be able to configure the association.
244
+ Remember that our projects have pretty urls? So if you thought that url like
245
+ /projects/:project_title/tasks would be a problem, I can assure you it won't:
246
+
247
+ class TasksController < InheritedResources::Base
248
+ belongs_to :project, :finder => :find_by_title!, :param => :project_title
249
+ end
250
+
251
+ Check belongs_to file for more customization. :)
252
+
253
+ Nested belongs to
254
+ -----------------
255
+
256
+ Now, our Tasks get some Comments and you need to nest even deeper. Good
257
+ practices says that you should never nest more than two resources, but sometimes
258
+ you have to for security reasons. So this is an example of how you can do it:
259
+
260
+ class CommentsController < InheritedResources::Base
261
+ nested_belongs_to :project
262
+ nested_belongs_to :task
263
+ end
264
+
265
+ nested_belongs_to is actually just an alias to belongs_to. This is an
266
+ alternative declaration:
267
+
268
+ class CommentsController < InheritedResources::Base
269
+ belongs_to :project do
270
+ belongs_to :task
271
+ end
272
+ end
273
+
274
+ Polymorphic belongs to
275
+ ----------------------
276
+
277
+ Now let's go even further. Our Projects is getting some Files and Messages
278
+ besides Tasks, and they are all commentable:
279
+
280
+ class CommentsController < InheritedResources::Base
281
+ belongs_to :task, :file, :message, :polymorphic => true
282
+ end
283
+
284
+ You can even use it with nested resources:
285
+
286
+ class CommentsController < InheritedResources::Base
287
+ belongs_to :project do
288
+ belongs_to :task, :file, :message, :polymorphic => true
289
+ end
290
+ end
291
+
292
+ When using polymorphic associations, you get some free helpers:
293
+
294
+ parent? #=> true
295
+ parent_type #=> :task
296
+ parent_class #=> Task
297
+ parent_instance #=> @task
298
+
299
+ Polymorphic controller is another great idea by James Golick and he also uses
300
+ that on resource_controller.
301
+
302
+ Singletons
303
+ ----------
304
+
305
+ Now we are going to add manager to projects. We say that Manager is a singleton
306
+ resource because a Project has just one manager. You should declare it as
307
+ has_one (or resource) in your routes.
308
+
309
+ To declare an association as singleton, you just have to give the :singleton
310
+ option.
311
+
312
+ class ManagersController < InheritedResources::Base
313
+ belongs_to :project, :singleton => true
314
+ end
315
+
316
+ It will deal with everything again and hide the action :index from you.
317
+
318
+ URL Helpers
319
+ -----------
320
+
321
+ When you use InheritedResources it creates some URL helpers for you.
322
+ And they handle everything for you.
323
+
324
+ # /posts/1/comments
325
+ resource_url # => /posts/1/comments/#{@comment.to_param}
326
+ resource_url(comment) # => /posts/1/comments/#{comment.to_param}
327
+ new_resource_url # => /posts/1/comments/new
328
+ edit_resource_url # => /posts/1/comments/#{@comment.to_param}/edit
329
+ collection_url # => /posts/1/comments
330
+
331
+ # /projects/1/tasks
332
+ resource_url # => /products/1/tasks/#{@task.to_param}
333
+ resource_url(task) # => /products/1/tasks/#{task.to_param}
334
+ new_resource_url # => /products/1/tasks/new
335
+ edit_resource_url # => /products/1/tasks/#{@task.to_param}/edit
336
+ collection_url # => /products/1/tasks
337
+
338
+ # /users
339
+ resource_url # => /users/#{@user.to_param}
340
+ resource_url(user) # => /users/#{user.to_param}
341
+ new_resource_url # => /users/new
342
+ edit_resource_url # => /users/#{@user.to_param}/edit
343
+ collection_url # => /users
344
+
345
+ The nice thing is that those urls are not guessed during runtime. They are
346
+ all created when your application is loaded (except for polymorphic
347
+ associations, that relies on Rails polymorphic_url).
348
+
349
+ What's next
350
+ -----------
351
+
352
+ I'm working on generators and some nice things to speed up and make easier
353
+ your controllers tests with mocking and stubs. :)
354
+
355
+ Bugs and Feedback
356
+ -----------------
357
+
358
+ If you discover any bugs, please send an e-mail to jose.valim@gmail.com
359
+ If you just want to give some positive feedback or drop a line, that's fine too!
360
+
361
+ Copyright (c) 2009 José Valim
362
+ http://josevalim.blogspot.com/
data/Rakefile ADDED
@@ -0,0 +1,19 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ desc 'Run tests for InheritedResources.'
6
+ Rake::TestTask.new(:test) do |t|
7
+ t.pattern = 'test/**/*_test.rb'
8
+ t.verbose = true
9
+ end
10
+
11
+ desc 'Generate documentation for InheritedResources.'
12
+ Rake::RDocTask.new(:rdoc) do |rdoc|
13
+ rdoc.rdoc_dir = 'rdoc'
14
+ rdoc.title = 'InheritedResources'
15
+ rdoc.options << '--line-numbers' << '--inline-source'
16
+ rdoc.rdoc_files.include('README')
17
+ rdoc.rdoc_files.include('MIT-LICENSE')
18
+ rdoc.rdoc_files.include('lib/**/*.rb')
19
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require File.join(File.dirname(__FILE__), 'lib', 'inherited_resources')
@@ -0,0 +1,4 @@
1
+ dir = File.dirname(__FILE__)
2
+ require File.join(dir, 'inherited_resources', 'respond_to')
3
+
4
+ module InheritedResources; end
@@ -0,0 +1,272 @@
1
+ # = Inheriting
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 projects_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 projects_url }
69
+ # end
70
+ # end
71
+ # end
72
+ #
73
+ # Since this is actually Ruby (and not a new DSL), if you want to do something
74
+ # before creating the project that is to small to deserve a before_filter, you
75
+ # could simply do:
76
+ #
77
+ # class ProjectController < InheritedResources::Base
78
+ # def create
79
+ # # do something different!
80
+ # create!
81
+ # end
82
+ # end
83
+ #
84
+ # And as instance variables are shared you can do more nice things.
85
+ # Let's suppose you want to create a project based on the current user:
86
+ #
87
+ # class ProjectController < InheritedResources::Base
88
+ # def create
89
+ # @project = @current_user.projects.build(params[:project])
90
+ # create!
91
+ # end
92
+ # end
93
+ #
94
+ # When you call create! the instance variable @project is already defined,
95
+ # so the method won't instanciate it again.
96
+ #
97
+ # The great thing is that we are not using blocks or nothing in special. We are
98
+ # just inheriting and calling the parent (super). You can extend even more
99
+ # without using blocks, please check helpers.rb for more info.
100
+ #
101
+ # = Flash and I18n
102
+ #
103
+ # Flash messages are changed through I18n API. If you have a ProjectsController,
104
+ # when a resource is updated with success, it will search for messages in the
105
+ # following order:
106
+ #
107
+ # 'flash.projects.update.notice'
108
+ # 'flash.actions.update.notice'
109
+ #
110
+ # If none of them are not available, it will show the default message:
111
+ #
112
+ # Project was successfully updated.
113
+ #
114
+ # The message will be set into flash[:notice].
115
+ # Messages can be interpolated, so you can do the following in your I18n files:
116
+ #
117
+ # flash:
118
+ # actions:
119
+ # update:
120
+ # notice: "Hooray! {{resource}} was updated with success!"
121
+ #
122
+ # It will replace {{resource}} by Project.human_name, which is also localized
123
+ # (check http://rails-i18n.org/wiki/pages/i18n-rails-guide for more info).
124
+ #
125
+ # But sometimes, flash messages are not that simple. You might want to say the
126
+ # the name of the project when it's updated. Well, that's easy also:
127
+ #
128
+ # flash:
129
+ # projects:
130
+ # update:
131
+ # notice: "Dear manager, {{project_name}} was successfully updated!"
132
+ #
133
+ # Since :project_name is not available for interpolation by default, you
134
+ # have to overwrite interpolation_options method on your controller.
135
+ #
136
+ # def interpolation_options
137
+ # { :project_name => @project.quoted_name }
138
+ # end
139
+ #
140
+ # Then you will finally have:
141
+ #
142
+ # 'Dear manager, "Make Rails Scale" was successfully updated!'
143
+ #
144
+ # Success messages appear on :create, :update and :destroy actions. Failure
145
+ # messages appear only on :create and :update.
146
+ #
147
+ # = Changing assumptions
148
+ #
149
+ # When you inherit from InheritedResources::Base, we make some assumptions on
150
+ # what is your resource_class, instance_name and collection_name.
151
+ #
152
+ # You can change those values by calling the class method defaults:
153
+ #
154
+ # class PeopleController < InheritedResources::Base
155
+ # defaults :resource_class => User, :instance_name => 'user', :collection_name => 'users'
156
+ # end
157
+ #
158
+ # Further customizations can be done replacing some methods. Check
159
+ # base_helpers.rb file for more information.
160
+ #
161
+ module InheritedResources
162
+ RESOURCES_ACTIONS = [ :index, :show, :new, :edit, :create, :update, :destroy ]
163
+
164
+ class Base < ::ApplicationController
165
+ include InheritedResources::BaseHelpers
166
+ extend InheritedResources::BelongsTo
167
+ extend InheritedResources::ClassMethods
168
+
169
+ helper_method :collection_url, :collection_path, :resource_url, :resource_path,
170
+ :new_resource_url, :new_resource_path, :edit_resource_url, :edit_resource_path
171
+
172
+ def self.inherited(base)
173
+ base.class_eval do
174
+ # Make all resources actions public
175
+ public *RESOURCES_ACTIONS
176
+ end
177
+
178
+ # Call super to register class in ApplicationController
179
+ super
180
+
181
+ # Creates and sets class accessors default values
182
+ initialize_resources_class_accessors!(base)
183
+ end
184
+
185
+ protected
186
+
187
+ # GET /resources
188
+ def index(&block)
189
+ respond_to(:with => collection, &block)
190
+ end
191
+ alias :index! :index
192
+
193
+ # GET /resources/1
194
+ def show(&block)
195
+ respond_to(:with => resource, &block)
196
+ end
197
+ alias :show! :show
198
+
199
+ # GET /resources/new
200
+ def new(&block)
201
+ respond_to(:with => build_resource, &block)
202
+ end
203
+ alias :new! :new
204
+
205
+ # GET /resources/1/edit
206
+ def edit(&block)
207
+ respond_to(:with => resource, &block)
208
+ end
209
+ alias :edit! :edit
210
+
211
+ # POST /resources
212
+ def create(&block)
213
+ object = build_resource(params[resource_instance_name])
214
+
215
+ if object.save
216
+ set_flash_message!(:notice, '{{resource}} was successfully created.')
217
+
218
+ respond_to(:with => object, :status => :created, :location => resource_url) do |format|
219
+ yield(format) if block_given?
220
+ format.html { redirect_to(resource_url) }
221
+ end
222
+ else
223
+ set_flash_message!(:error)
224
+
225
+ respond_to(:with => object.errors, :status => :unprocessable_entity) do |format|
226
+ yield(format) if block_given?
227
+ format.html { render :action => "new" }
228
+ end
229
+ end
230
+ end
231
+ alias :create! :create
232
+
233
+ # PUT /resources/1
234
+ def update(&block)
235
+ object = resource
236
+
237
+ if object.update_attributes(params[resource_instance_name])
238
+ set_flash_message!(:notice, '{{resource}} was successfully updated.')
239
+
240
+ respond_to do |format|
241
+ yield(format) if block_given?
242
+ format.html { redirect_to(resource_url) }
243
+ format.all { head :ok }
244
+ end
245
+ else
246
+ set_flash_message!(:error)
247
+
248
+ respond_to(:with => object.errors, :status => :unprocessable_entity) do |format|
249
+ yield(format) if block_given?
250
+ format.html { render :action => "edit" }
251
+ end
252
+ end
253
+ end
254
+ alias :update! :update
255
+
256
+ # DELETE /resources/1
257
+ def destroy(&block)
258
+ resource.destroy
259
+
260
+ set_flash_message!(:notice, '{{resource}} was successfully destroyed.')
261
+
262
+ respond_to do |format|
263
+ yield(format) if block_given?
264
+ format.html { redirect_to(collection_url) }
265
+ format.all { head :ok }
266
+ end
267
+ end
268
+ alias :destroy! :destroy
269
+
270
+ end
271
+ end
272
+