make_resourceful
I just (well, as of last night) got back from RailsConf 2007, which I was attending courtesy of Unspace as a sort of thank-you for working on Haml. It was great fun. I got to meet many awesome people, including Hampton Catlin, with whom I’ve been working on Haml for a long time but whom I’ve never seen in person, as well as the rest of the Unspace team; various folks with whom I’ve talked on the Haml, Scribble, and Hackety Hack mailing lists; a couple members of the Rails core team; and too many other people to list here.
I also went to lots of engaging (and a couple boring) talks.
By far the most interesting of these was a talk on a soon-to-be-released plugin
called make_resourceful.
The basic idea is to DRY up the code
in RESTful controllers.
Even with the new Rails support for REST,
there’s some code that’s just always repeated.
For example, for even a minimalistic update:
def update @person = Person.find(params[:id]) if @person.update_attributes params[:person] redirect_to person_url(@person) else redirect_to :back end end
Now, that’s not terrible. It’s only six lines.
Most of the other typical RESTful actions
(index, show, new, edit, create, update, destroy)
are similar in length or shorter.
But they’re all the same; the code is repeated over and over again.
And when you get to having nested resources the code gets messier:
def update @group = Group.find(params[:group_id]) @person = @group.people.find(params[:id]) if @person.update_attributes params[:person] redirect_to person_url(@group, @person) else redirect_to :back end end
And what if you want to expose, say, an XML representation?
def update @group = Group.find(params[:group_id]) @person = @group.people.find(params[:id]) if @person.update_attributes params[:person] redirect_to person_url(@group, @person) end else respond_to do |format| format.html { redirect_to :back } format.xml { render :xml => @person.errors.to_xml, :status => "422 Unprocessable Entity" } end end end
What if you wanted to use JSON as well? YAML? What if we didn’t want to expose the person’s password hash and email? It would quickly grow into an unholy mess. But it’s all repeated! We should be able to do something about that!
Well, with make_resourceful, we can.
To define our ugly, ugly update function above,
all we have to say is
class PeopleController make_resourceful do build :update belongs_to :group publish :html, :xml end end
Yes, it’s that simple.
build tells make_resourceful to make the default update action.
belongs_to shows the inheritance relationship.
publish tells it which representations to make available.
Everything else is done behind the scenes.
Also, check out the syntax:
everything’s going on within that one block.
This allows the plugin to have more control over the syntax
while avoiding the possibility overwriting normal controller methods.
Awesome, no?
Alright, it’s time for full disclosure.
I confess: I’m not exactly unbiased in my observations.
I didn’t just happen across make_resourceful at RailsConf;
it’s Hampton’s latest project,
along with Jeff Hardy (also of Unspace),
and I knew about it a good while beforehand.
In fact, I’m helping to implement it,
and thus am listed as a co-creator
(although all the ideas came from Hampton and Jeff).
But nevertheless, it’s still an awesome plugin! Not only is it excellent at making all the stuff you’d normally want to do quick and easy, it also provides plentiful callbacks so you can customize the behavior. For instance, if you wanted to log how many times someone’s profile was viewed:
make_resourceful do build :show, :index before(:show) { @person.profile_views += 1 } end
And what if you wanted to set snappy flash messages?
make_resourceful do build :edit, :new, :update, :create after(:update, :create) { flash[:notice] = "You did it! Congrats!" } after(:update_fails, :create_fails) { flash[:error] = "You failed! Jerk!" } end
Or only expose a user’s name, id, and comment bodies to the world at large?
make_resourceful do build :all publish :html, :xml, :yaml, :json, :attributes => [:name, :id, {:comments => :body}] end
Now, I know this is all very exciting, but it’s not quite available yet. It’s almost ready, but not quite. There are still a few implementation details to work out, and the syntax is still a little up in the air. I predict it’ll be available within the week; when it is, the syntax may be a bit different, but all the awesomeness will still be there. I’ll make sure to mention when it is released.
Finally, I also reccomend that you check out
Hampton’s post
on his make_resourceful presentation.
It has the (hilarious) slides he used!
About Me
Hackety Hack Experiences


