make_resourceful 1.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.
Files changed (40) hide show
  1. data/Rakefile +31 -0
  2. data/Readme.rdoc +229 -0
  3. data/VERSION +1 -0
  4. data/lib/make_resourceful.rb +11 -0
  5. data/lib/resourceful/base.rb +63 -0
  6. data/lib/resourceful/builder.rb +405 -0
  7. data/lib/resourceful/default/accessors.rb +418 -0
  8. data/lib/resourceful/default/actions.rb +101 -0
  9. data/lib/resourceful/default/callbacks.rb +51 -0
  10. data/lib/resourceful/default/responses.rb +118 -0
  11. data/lib/resourceful/default/urls.rb +136 -0
  12. data/lib/resourceful/generators/resourceful_scaffold/resourceful_scaffold_generator.rb +87 -0
  13. data/lib/resourceful/generators/resourceful_scaffold/templates/controller.rb +5 -0
  14. data/lib/resourceful/generators/resourceful_scaffold/templates/fixtures.yml +10 -0
  15. data/lib/resourceful/generators/resourceful_scaffold/templates/functional_test.rb +50 -0
  16. data/lib/resourceful/generators/resourceful_scaffold/templates/helper.rb +2 -0
  17. data/lib/resourceful/generators/resourceful_scaffold/templates/migration.rb +13 -0
  18. data/lib/resourceful/generators/resourceful_scaffold/templates/model.rb +2 -0
  19. data/lib/resourceful/generators/resourceful_scaffold/templates/unit_test.rb +7 -0
  20. data/lib/resourceful/generators/resourceful_scaffold/templates/view__form.haml +5 -0
  21. data/lib/resourceful/generators/resourceful_scaffold/templates/view_edit.haml +11 -0
  22. data/lib/resourceful/generators/resourceful_scaffold/templates/view_index.haml +5 -0
  23. data/lib/resourceful/generators/resourceful_scaffold/templates/view_new.haml +9 -0
  24. data/lib/resourceful/generators/resourceful_scaffold/templates/view_partial.haml +12 -0
  25. data/lib/resourceful/generators/resourceful_scaffold/templates/view_show.haml +14 -0
  26. data/lib/resourceful/maker.rb +92 -0
  27. data/lib/resourceful/response.rb +33 -0
  28. data/lib/resourceful/serialize.rb +185 -0
  29. data/spec/accessors_spec.rb +474 -0
  30. data/spec/actions_spec.rb +310 -0
  31. data/spec/base_spec.rb +12 -0
  32. data/spec/builder_spec.rb +332 -0
  33. data/spec/callbacks_spec.rb +71 -0
  34. data/spec/integration_spec.rb +394 -0
  35. data/spec/maker_spec.rb +91 -0
  36. data/spec/response_spec.rb +37 -0
  37. data/spec/responses_spec.rb +314 -0
  38. data/spec/serialize_spec.rb +133 -0
  39. data/spec/urls_spec.rb +282 -0
  40. metadata +97 -0
data/Rakefile ADDED
@@ -0,0 +1,31 @@
1
+ require 'rake'
2
+ require 'rake/rdoctask'
3
+ require 'spec/rake/spectask'
4
+
5
+ desc 'Default: run specs.'
6
+ task :default => :spec
7
+
8
+ spec_files = Rake::FileList["spec/**/*_spec.rb"]
9
+
10
+ desc "Run specs"
11
+ Spec::Rake::SpecTask.new do |t|
12
+ t.spec_files = spec_files
13
+ t.spec_opts = ["-c"]
14
+ end
15
+
16
+ desc "Generate code coverage"
17
+ Spec::Rake::SpecTask.new(:coverage) do |t|
18
+ t.spec_files = spec_files
19
+ t.rcov = true
20
+ t.rcov_opts = ['--exclude', 'spec,/var/lib/gems']
21
+ end
22
+
23
+ desc 'Generate documentation for the make_resourceful plugin.'
24
+ Rake::RDocTask.new(:rdoc) do |rdoc|
25
+ rdoc.rdoc_dir = 'rdoc'
26
+ rdoc.title = 'make_resourceful'
27
+ rdoc.options << '--line-numbers' << '--inline-source'
28
+ rdoc.main = 'README'
29
+ rdoc.rdoc_files.include(FileList.new('*').exclude(/[^A-Z0-9]/))
30
+ rdoc.rdoc_files.include('lib/**/*.rb')
31
+ end
data/Readme.rdoc ADDED
@@ -0,0 +1,229 @@
1
+ = make_resourceful
2
+ ===== Take back control of your Controllers. Make them awesome. Make them sleek. Make them resourceful.
3
+
4
+ REST is a fine pattern for designing controllers,
5
+ but it can be pretty repetitive.
6
+ Who wants to write out the same actions and copy the same model lookup logic
7
+ all over their application?
8
+
9
+ make_resourceful handles all that for you.
10
+ It sets up all your RESTful actions and responses with next to no code.
11
+ Everything has full, sensible default functionality.
12
+
13
+ Of course, no controller _only_ uses the defaults.
14
+ So make_resourceful can be massively customized,
15
+ while still keeping your controllers trim and readable.
16
+
17
+ == Get it!
18
+
19
+ Rails 3.0+
20
+
21
+ gem "make_resourceful" #ZOMG, SO EASY
22
+
23
+ Git
24
+
25
+ $ git clone git://github.com/hcatlin/make_resourceful.git
26
+
27
+ == Use it!
28
+
29
+ If you want to try make_resourceful on one of your current controllers,
30
+ just replace the mess of repetition with this:
31
+
32
+ class FooController < ApplicationController
33
+ make_resourceful do
34
+ actions :all
35
+ end
36
+ end
37
+
38
+ Those three lines will replace the entire default controller
39
+ that comes out of the scaffold_resource generator.
40
+
41
+ === Really?
42
+
43
+ Yes.
44
+
45
+ === Can I do nested resources?
46
+
47
+ make_resourceful do
48
+ actions :all
49
+ belongs_to :post
50
+ end
51
+
52
+ === What if I want to use fancy permalinks?
53
+
54
+ def current_object
55
+ @current_object ||= current_model.find_by_permalink(params[:id])
56
+ end
57
+
58
+ === What about paging?
59
+
60
+ def current_objects
61
+ @current_objects ||= current_model.find(:all,
62
+ :order => "created_at DESC", :page => {:current => params[:page], :size => 10 } )
63
+ end
64
+
65
+ === What if I want to do something in the middle of an action?
66
+
67
+ before :show, :index do
68
+ @page_title = "Awesome!"
69
+ end
70
+
71
+ after :create_fails do
72
+ @page_title = "Not So Awesome!"
73
+ end
74
+
75
+ === What about all of my awesome respond_to blocks for my XML APIs and RJS responses?
76
+
77
+ response_for :show do |format|
78
+ format.html
79
+ format.js
80
+ format.xml
81
+ end
82
+
83
+ response_for :update_fails do |format|
84
+ format.html { render :action => 'edit' }
85
+ format.json { render :json => false.to_json, :status => 422 }
86
+ end
87
+
88
+ === So I guess I have to write responses for all my actions?
89
+
90
+ Nope! make_resourceful makes them do the right thing by default.
91
+ You only need to customize them if you want to do something special.
92
+
93
+ === Seriously?!
94
+
95
+ Yes!
96
+
97
+ == Grok it!
98
+
99
+ === +make_resourceful+ the Method
100
+
101
+ The +make_resourceful+ block is where most of the action happens.
102
+ Here you specify which actions you want to auto-generate,
103
+ what code you want to run for given callbacks,
104
+ and so forth.
105
+
106
+ You also use the block to declare various bits of information about your controller.
107
+ For instance, if the controller is nested, you'd call +belongs_to+.
108
+ If you wanted to expose your models as some sort of text format,
109
+ you'd call +publish+.
110
+
111
+ Check out the documentation of Resourceful::Builder
112
+ for more information on the methods you can call here.
113
+
114
+ === Helper Methods
115
+
116
+ make_resourceful provides lots of useful methods
117
+ that can be used in your callbacks and in your views.
118
+ They range from accessing the records you're looking up
119
+ to easily generating URLs for a record
120
+ to getting information about the action itself.
121
+
122
+ Two of the most useful methods are +current_object+ and +current_objects+
123
+ (note the subtle plurality difference).
124
+ +current_objects+ only works for +index+,
125
+ and returns all the records in the current model.
126
+ +current_object+ works for all actions other than +index+,
127
+ and returns the record that's currently being dealt with.
128
+
129
+ The full documentation of the helper methods
130
+ is in Resourceful::Default::Accessors and Resourceful::Default::URLs.
131
+
132
+ === Nested Resources
133
+
134
+ make_resourceful supports easy management of nested resources.
135
+ This is set up with the Resourceful::Builder#belongs_to declaration.
136
+ Pass in the name of the parent model,
137
+
138
+ belongs_to :user
139
+
140
+ and everything will be taken care of.
141
+ When +index+ is run for GET /users/12/albums,
142
+ parent_object
143
+ will get <tt>User.find(params[:user_id])</tt>,
144
+ and current_objects
145
+ will get <tt>parent_object.albums</tt>.
146
+ When +create+ is run for POST /users/12/albums,
147
+ the newly created Album will automatically belong to the user
148
+ with id 12.
149
+
150
+ The normal non-scoped actions still work, too.
151
+ GET /albums/15 runs just fine.
152
+ make_resourceful knows that since there's no <tt>params[:user_id]</tt>,
153
+ you just want to deal with the album.
154
+
155
+ You can even have a single resource nested under several different resources.
156
+ Just pass multiple parent names to the Resourceful::Builder#belongs_to, like
157
+
158
+ belongs_to :user, :artist
159
+
160
+ Then /users/15/albums and /artists/7/albums will both work.
161
+
162
+ This does, however, mean that make_resourceful only supports one level of nesting.
163
+ There's no automatic handling of /users/15/collections/437/albums.
164
+ However, this is really the best way to organize most resources anyway;
165
+ see this {article}[http://weblog.jamisbuck.org/2007/2/5/nesting-resources].
166
+
167
+ If you really need a deeply nested controller,
168
+ it should be easy enough to set up on your own.
169
+ Just override current_model.
170
+ See the next section for more details.
171
+
172
+ === Overriding Methods
173
+
174
+ Not only are helper methods useful to the developer to use,
175
+ they're used internally by the actions created by make_resourceful.
176
+ Thus one of the main ways make_resourceful can be customized
177
+ is by overriding accessors.
178
+
179
+ For instance, if you want to only look up the 10 most recent records for +index+,
180
+ you're override +current_objects+.
181
+ If you wanted to use a different model than that suggested by the name of the controller,
182
+ you'd override +current_model+.
183
+
184
+ When you're overriding methods that do SQL lookups, though, be a little cautious.
185
+ By default, these methods cache their values in instance variables
186
+ so that multiple SQL queries aren't run on multiple calls.
187
+ When overriding them, it's wise for you to do the same.
188
+ For instance,
189
+
190
+ def current_object
191
+ @current_object ||= current_model.find_by_name(params[:name])
192
+ end
193
+
194
+ === For More Information...
195
+
196
+ Haven't found all the information you need in the RDoc?
197
+ Still a little confused about something?
198
+ Don't despair, there are still more resources available!
199
+
200
+ * Read the source code!
201
+ It's very straightforward,
202
+ and make_resourceful is built to encourage overriding methods
203
+ and hacking the source.
204
+ * Nathan Weizenbaum has some good blog posts about make_resourceful.
205
+ They may be a little outdated, but they should still be useful and explanatory.
206
+ * On nesting and associations: {here}[http://nex-3.com/posts/55-nesting-and-make_resourceful].
207
+ * An overview of make_resourceful 0.2.0 and 0.2.2: {here}[http://localhost:3000/posts/54-make_resourceful-0-2-0].
208
+ * On Resourceful::Builder#publish
209
+ and Resourceful::Serialize:
210
+ {here}[http://nex-3.com/posts/35-make_resourceful-the-basics-of-publish] and
211
+ {here}[http://nex-3.com/posts/36-make_resourceful-publish-extras].
212
+ * There's an excellent, active Google Group http://groups.google.com/group/make_resourceful
213
+ where people will be happy to answer your questions.
214
+
215
+ ---
216
+
217
+ Copyright 2007-2010 Hampton Catlin and Nathan Weizenbaum.
218
+ Contributions by:
219
+
220
+ * Russell Norris
221
+ * Jonathan Linowes
222
+ * Cristi Balan
223
+ * Mike Ferrier
224
+ * James Golick
225
+ * Don Petersen
226
+ * Alex Ross
227
+ * Tom Stuart
228
+ * Glenn Powell
229
+ * Johannes Jörg Schmidt
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0
@@ -0,0 +1,11 @@
1
+
2
+ class MakeResourcefulTie < Rails::Railtie
3
+ initializer "my_railtie.configure_rails_initialization" do
4
+ require_relative 'resourceful/maker'
5
+ ActionController::Base.extend Resourceful::Maker
6
+ end
7
+
8
+ generators do
9
+ #require_relative 'resourceful/generators/resourceful_scaffold/resourceful_scaffold_generator'
10
+ end
11
+ end
@@ -0,0 +1,63 @@
1
+ # The module containing all the code for make_resourceful.
2
+ #
3
+ # For methods available in the +make_resourceful+ block,
4
+ # see Resourceful::Builder.
5
+ #
6
+ # For helper methods and methods you can override
7
+ # to customize the behavior of your actions,
8
+ # see Resourceful::Default::Accessors
9
+ # and Resourceful::Default::URLs.
10
+ module Resourceful
11
+ # We want to define some stuff before we load other modules
12
+
13
+ # The default actions generated by make_resourceful.
14
+ ACTIONS = [:index, :show, :edit, :update, :create, :new, :destroy]
15
+
16
+ # The actions that modify the database.
17
+ MODIFYING_ACTIONS = [:update, :create, :destroy]
18
+
19
+ # The actions that act on multiple records.
20
+ PLURAL_ACTIONS = [:index]
21
+
22
+ # The actions that act on just one record.
23
+ SINGULAR_ACTIONS = ACTIONS - PLURAL_ACTIONS
24
+
25
+ # The actions that act on just one record.
26
+ SINGULAR_PRELOADED_ACTIONS = SINGULAR_ACTIONS - [:new, :create]
27
+ end
28
+
29
+ require 'resourceful/default/accessors'
30
+ require 'resourceful/default/responses'
31
+ require 'resourceful/default/callbacks'
32
+ require 'resourceful/default/urls'
33
+
34
+ # All modules included by this module
35
+ # are made available to the controller as accessors.
36
+ module Resourceful::Base
37
+ @@made_resourceful_callbacks = []
38
+
39
+ # This method is meant to be called by included classes.
40
+ # It takes a block of the same form as that given to Maker#make_resourceful.
41
+ # The Maker will then run that block
42
+ # along with the blocks given by the individual controllers.
43
+ def self.made_resourceful(&block)
44
+ if block
45
+ @@made_resourceful_callbacks << block
46
+ else
47
+ @@made_resourceful_callbacks
48
+ end
49
+ end
50
+
51
+ include Resourceful::Default::Accessors
52
+ include Resourceful::Default::Responses
53
+ include Resourceful::Default::Callbacks
54
+ include Resourceful::Default::URLs
55
+
56
+ # FIXME HACK
57
+ # making methods assigned to controller private
58
+ # prevents access from dispatcher.
59
+ private *Resourceful::Default::Accessors.public_instance_methods
60
+ private *Resourceful::Default::Responses.public_instance_methods
61
+ private *Resourceful::Default::Callbacks.public_instance_methods
62
+ private *Resourceful::Default::URLs.public_instance_methods
63
+ end