jcfischer / make_resourceful
- Source
- Commits
- Network (4)
- Issues (0)
- Downloads (0)
- Wiki (1)
- Graphs
-
Tree:
26c3e01
make_resourceful / README
| 549aeb5a » | nex3 | 2007-10-30 | 1 | = make_resourceful | |
| 2 | ===== Take back control of your Controllers. Make them awesome. Make them sleek. Make them resourceful. | ||||
| 8c28892d » | nex3 | 2007-10-30 | 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 | |||||
| 549aeb5a » | nex3 | 2007-10-30 | 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. | ||||
| 8c28892d » | nex3 | 2007-10-30 | 12 | ||
| 549aeb5a » | nex3 | 2007-10-30 | 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 | ||||
| 20 | |||||
| 21 | $ ruby script/plugin install http://svn.hamptoncatlin.com/make_resourceful/trunk | ||||
| 22 | $ mv vendor/plugins/trunk vendor/plugins/make_resourceful | ||||
| 23 | |||||
| 24 | Subversion | ||||
| 25 | |||||
| 26 | $ svn co http://svn.hamptoncatlin.com/make_resourceful/trunk make_resourceful | ||||
| 27 | |||||
| 28 | == Use it! | ||||
| 29 | |||||
| 30 | The easiest way to start with make_resourceful | ||||
| 31 | is to run the resource_scaffold generator. | ||||
| 32 | It uses the same syntax as the Rails scaffold_resource generator: | ||||
| 33 | |||||
| 34 | $ script/generate resource_scaffold post title:string body:text | ||||
| 35 | |||||
| 36 | It does, however, require Haml[http://haml.hamptoncatlin.com]. | ||||
| 37 | You _are_ using Haml, right? No? | ||||
| 38 | I'll wait here while you go fall in love with it. | ||||
| 39 | |||||
| 40 | If you want to try make_resourceful on one of your current controllers, | ||||
| 41 | just replace the mess of repetition with this: | ||||
| 42 | |||||
| 43 | class FooController < ApplicationController | ||||
| 8c28892d » | nex3 | 2007-10-30 | 44 | make_resourceful do | |
| 45 | actions :all | ||||
| 46 | end | ||||
| 47 | end | ||||
| 48 | |||||
| 549aeb5a » | nex3 | 2007-10-30 | 49 | Those three lines will replace the entire default controller | |
| 50 | that comes out of the scaffold_resource generator. | ||||
| 51 | |||||
| 52 | === Really? | ||||
| 53 | |||||
| 54 | Yes. | ||||
| 55 | |||||
| 56 | === Can I do nested resources? | ||||
| 57 | |||||
| 58 | make_resourceful do | ||||
| 59 | actions :all | ||||
| 60 | belongs_to :post | ||||
| 61 | end | ||||
| 62 | |||||
| 63 | === What if I want to use fancy permalinks? | ||||
| 64 | |||||
| 65 | def current_object | ||||
| c0e0ab7e » | nex3 | 2007-10-30 | 66 | @current_object ||= current_model.find_by_permalink(params[:id]) | |
| 549aeb5a » | nex3 | 2007-10-30 | 67 | end | |
| 68 | |||||
| 69 | === What about paging? | ||||
| 70 | |||||
| 71 | def current_objects | ||||
| c0e0ab7e » | nex3 | 2007-10-30 | 72 | @current_object ||= current_model.find(:all, | |
| 73 | :order => "created_at DESC", :page => {:current => params[:page], :size => 10 } ) | ||||
| 549aeb5a » | nex3 | 2007-10-30 | 74 | end | |
| 75 | |||||
| 76 | === What if I want to do something in the middle of an action? | ||||
| 77 | |||||
| 78 | before :show, :index do | ||||
| 79 | @page_title = "Awesome!" | ||||
| 80 | end | ||||
| 81 | |||||
| 82 | after :create_fails do | ||||
| 83 | @page_title = "Not So Awesome!" | ||||
| 84 | end | ||||
| 85 | |||||
| 86 | === What about all of my awesome respond_to blocks for my XML APIs and RJS responses? | ||||
| 87 | |||||
| 88 | response_for :show do |format| | ||||
| 89 | format.html | ||||
| 90 | format.js | ||||
| 91 | format.xml | ||||
| 92 | end | ||||
| 93 | |||||
| 94 | response_for :update_fails do |format| | ||||
| 95 | format.html { render :action => 'edit' } | ||||
| 96 | format.json { render :json => false.to_json, :status => 422 } | ||||
| 97 | end | ||||
| 98 | |||||
| 99 | === So I guess I have to write responses for all my actions? | ||||
| 100 | |||||
| 101 | Nope! make_resourceful makes them do the right thing by default. | ||||
| 102 | You only need to customize them if you want to do something special. | ||||
| 103 | |||||
| 104 | === Seriously?! | ||||
| 105 | |||||
| 106 | Yes! | ||||
| 107 | |||||
| bb0245ab » | nex3 | 2007-10-31 | 108 | == Grok it! | |
| 109 | |||||
| 110 | === +make_resourceful+ the Method | ||||
| 111 | |||||
| 112 | The +make_resourceful+ block is where most of the action happens. | ||||
| 113 | Here you specify which actions you want to auto-generate, | ||||
| 114 | what code you want to run for given callbacks, | ||||
| 115 | and so forth. | ||||
| 116 | |||||
| 117 | You also use the block to declare various bits of information about your controller. | ||||
| 118 | For instance, if the controller is nested, you'd call +belongs_to+. | ||||
| 119 | If you wanted to expose your models as some sort of text format, | ||||
| 120 | you'd call +publish+. | ||||
| 121 | |||||
| 122 | Check out the documentation of Resourceful::Builder | ||||
| 123 | for more information on the methods you can call here. | ||||
| 124 | |||||
| 125 | === Helper Methods | ||||
| 126 | |||||
| 127 | make_resourceful provides lots of useful methods | ||||
| 128 | that can be used in your callbacks and in your views. | ||||
| 129 | They range from accessing the records you're looking up | ||||
| 130 | to easily generating URLs for a record | ||||
| 131 | to getting information about the action itself. | ||||
| 132 | |||||
| 133 | Two of the most useful methods are +current_object+ and +current_objects+ | ||||
| 134 | (note the subtle plurality difference). | ||||
| 135 | +current_objects+ only works for +index+, | ||||
| 136 | and returns all the records in the current model. | ||||
| 137 | +current_object+ works for all actions other than +index+, | ||||
| 138 | and returns the record that's currently being dealt with. | ||||
| 139 | |||||
| 140 | The full documentation of the helper methods | ||||
| 141 | is in Resourceful::Default::Accessors and Resourceful::Default::URLs. | ||||
| 142 | |||||
| 3fce2054 » | nex3 | 2007-11-14 | 143 | === Nested Resources | |
| 144 | |||||
| 145 | make_resourceful supports easy management of nested resources. | ||||
| 146 | This is set up with the Resourceful::Builder#belongs_to declaration. | ||||
| 147 | Pass in the name of the parent model, | ||||
| 148 | |||||
| 149 | belongs_to :user | ||||
| 150 | |||||
| 151 | and everything will be taken care of. | ||||
| 152 | When +index+ is run for GET /users/12/albums, | ||||
| 153 | parent_object[link:classes/Resourceful/Accessors.html#M000024] | ||||
| 154 | will get <tt>User.find(params[:user_id])</tt>, | ||||
| 155 | and current_objects[link:classes/Resourceful/Default/Accessors.html#M000010] | ||||
| 156 | will get <tt>parent_object.albums</tt>. | ||||
| 157 | When +create+ is run for POST /users/12/albums, | ||||
| 158 | the newly created Album will automatically belong to the user | ||||
| 159 | with id 12. | ||||
| 160 | |||||
| 161 | The normal non-scoped actions still work, too. | ||||
| 162 | GET /albums/15 runs just fine. | ||||
| 163 | make_resourceful knows that since there's no <tt>params[:user_id]</tt>, | ||||
| 164 | you just want to deal with the album. | ||||
| 165 | |||||
| 166 | You can even have a single resource nested under several different resources. | ||||
| 167 | Just pass multiple parent names to the Resourceful::Builder#belongs_to, like | ||||
| 168 | |||||
| 169 | belongs_to :user, :artist | ||||
| 170 | |||||
| 171 | Then /users/15/albums and /artists/7/albums will both work. | ||||
| 172 | |||||
| 173 | This does, however, mean that make_resourceful only supports one level of nesting. | ||||
| 174 | There's no automatic handling of /users/15/collections/437/albums. | ||||
| 175 | However, this is really the best way to organize most resources anyway; | ||||
| 176 | see this article[http://weblog.jamisbuck.org/2007/2/5/nesting-resources]. | ||||
| 177 | |||||
| 178 | If you really need a deeply nested controller, | ||||
| 179 | it should be easy enough to set up on your own. | ||||
| 180 | Just override current_model[link:classes/Resourceful/Default/Accessors.html#M000018]. | ||||
| 181 | See the next section for more details. | ||||
| 182 | |||||
| bb0245ab » | nex3 | 2007-10-31 | 183 | === Overriding Methods | |
| 184 | |||||
| 185 | Not only are helper methods useful to the developer to use, | ||||
| 186 | they're used internally by the actions created by make_resourceful. | ||||
| 187 | Thus one of the main ways make_resourceful can be customized | ||||
| 188 | is by overriding accessors. | ||||
| 189 | |||||
| 190 | For instance, if you want to only look up the 10 most recent records for +index+, | ||||
| 191 | you're override +current_objects+. | ||||
| 192 | If you wanted to use a different model than that suggested by the name of the controller, | ||||
| 9d251e64 » | nex3 | 2007-11-04 | 193 | you'd override +current_model+. | |
| bb0245ab » | nex3 | 2007-10-31 | 194 | ||
| 195 | When you're overriding methods that do SQL lookups, though, be a little cautious. | ||||
| 196 | By default, these methods cache their values in instance variables | ||||
| 197 | so that multiple SQL queries aren't run on multiple calls. | ||||
| 198 | When overriding them, it's wise for you to do the same. | ||||
| 199 | For instance, | ||||
| 200 | |||||
| 201 | def current_object | ||||
| 202 | @current_object ||= current_model.find_by_name(params[:name]) | ||||
| 203 | end | ||||
| 204 | |||||
| 9d251e64 » | nex3 | 2007-11-04 | 205 | === For More Information... | |
| 206 | |||||
| 207 | Haven't found all the information you need in the RDoc? | ||||
| 208 | Still a little confused about something? | ||||
| 209 | Don't despair, there are still more resources available! | ||||
| 210 | |||||
| 211 | * Nathan Weizenbaum periodically makes blog posts about new features and versions of make_resourceful. | ||||
| 212 | They may be a little outdated, but they should still be useful and explanatory. | ||||
| de150bfc » | nex3 | 2007-11-15 | 213 | * On nesting and associations: here[http://nex-3.com/posts/55-nesting-and-make_resourceful]. | |
| a34bdc3b » | nbibler | 2008-04-12 | 214 | * An overview of make_resourceful 0.2.0 and 0.2.2: here[http://nex-3.com/posts/54-make_resourceful-0-2-0]. | |
| 9d251e64 » | nex3 | 2007-11-04 | 215 | * On Resourceful::Builder#publish[link:classes/Resourceful/Builder.html#M000061] | |
| 216 | and Resourceful::Serialize: | ||||
| 217 | here[http://nex-3.com/posts/35-make_resourceful-the-basics-of-publish] and | ||||
| 218 | here[http://nex-3.com/posts/36-make_resourceful-publish-extras]. | ||||
| 219 | * There's an excellent, active Google Group (link[http://groups.google.com/group/make_resourceful]) | ||||
| 220 | where people will be happy to answer your questions. | ||||
| 221 | * Read the source code! | ||||
| 222 | It's very straightforward, | ||||
| 223 | and make_resourceful is built to encourage overriding methods | ||||
| 224 | and hacking the source. | ||||
| 225 | |||||
| bb0245ab » | nex3 | 2007-10-31 | 226 | --- | |
| 8c28892d » | nex3 | 2007-10-30 | 227 | ||
| 228 | Copyright 2007 Hampton Catlin, Nathan Weizenbaum, and Jeff Hardy. | ||||
| 229 | |||||
| 230 | Contributions by: | ||||
| 231 | |||||
| c506addb » | nex3 | 2007-11-26 | 232 | * Russell Norris | |
| b3ad1d71 » | nex3 | 2007-11-15 | 233 | * Jonathan Linowes | |
| 8c28892d » | nex3 | 2007-10-30 | 234 | * Cristi Balan | |
| 235 | * Mike Ferrier | ||||
| 236 | * James Golick | ||||
| 237 | * Don Petersen | ||||
| 238 | * Alex Ross | ||||
| 239 | * Tom Stuart | ||||
