battle of the restful controller abstractions (boilerplate vs resource_controller vs inherited_resources vs ???)

136 views
Skip to first unread message

Josh Nichols

unread,
Aug 4, 2009, 2:50:42 PM8/4/09
to boston-r...@googlegroups.com
When Dan Croak was conducting the bostonrb.org code review last week,
we noticed that part of the project was using resource_controller, and
the rest was not.

The thought occurred, what if we did a side-by-side comparison of the
'normal' way of restful controllers, to using the various restful
controller abstractions, like resource_controller and
inherited_resources, for the entire app?

So I set out to do so. These were my goals:
- start from a baseline commit
(http://github.com/bostonrb/bostonrb/commit/9f92569536ea54952d8d873708b0c9cb8e7145fc)
- use the abstraction whenever boilerplate rest stuff is used
- tests and stories cannot be changed, and must pass

Here are the results:

The original code:
http://github.com/bostonrb/bostonrb/tree/master

Using resource_controller everywhere:
http://github.com/bostonrb/bostonrb/tree/resource_controller

Using inherited_resources everywhere:
http://github.com/bostonrb/bostonrb/tree/inherited_resources

With that, I'd like to open discussion on how good/bad it is to use
these abstractions, and how the implementation compare.

Additionally, if you have another contender you'd like to see battle,
just fork on bostonrb on github, make a branch for it, and report back
here.

- Josh

John Norman

unread,
Aug 4, 2009, 3:12:16 PM8/4/09
to boston-r...@googlegroups.com
Josh,

How about saying now which way you prefer and why?

John

Josh Nichols

unread,
Aug 4, 2009, 3:22:22 PM8/4/09
to boston-r...@googlegroups.com
My opinions on the matter are still marinating. They will be delicious
when they are ready though.

- Josh

John Norman

unread,
Aug 4, 2009, 3:26:31 PM8/4/09
to boston-r...@googlegroups.com
People have been known to take a bite and report on the flavor during the marination process.

Wyatt Greene

unread,
Aug 4, 2009, 3:28:04 PM8/4/09
to boston-r...@googlegroups.com
Patience; pickling takes time.  ;)

Dan Croak

unread,
Aug 4, 2009, 8:56:45 PM8/4/09
to boston-r...@googlegroups.com
I've spent the hackfest tonight comparing them and now have an informed opinion.

On Tue, Aug 4, 2009 at 3:12 PM, John Norman<jo...@7fff.com> wrote:

> How about saying now which way you prefer and why?

inherited_resources

It has more features and a more natural API.

More features: I18n API makes flashes as easy as a YAML file:

en:
flash:
actions:
create:
notice: "{{resource_name}} created."
update:
notice: "{{resource_name}} updated."
destroy:
notice: "{{resource_name}} deleted."
users:
update:
notice: "Account updated."
employees:
create:
success: "Employee added to company."

More features: has_scope encourages pushing logic into named_scopes on
the model.

More natural API: "No tricks, no DSL, just Ruby."

def destroy
super do |format|
format.html { redirect_to root_url }
end
end

but can be shortened to:

def destroy
destroy! do |format|
format.html { redirect_to root_url }
end
end

Nice inline overrides:

def create
@project = Project.new(params[:project])
@project.something_special!
create!
end

Success and failure blocks:

def update
update! do |success, failure|
failure.html { redirect_to project_url(@project) }
end
end

Some of this API stuff is just preference, but I prefer it.

--
Dan Croak
@Croaky

ni...@hanoian.com

unread,
Aug 4, 2009, 9:14:01 PM8/4/09
to boston-r...@googlegroups.com
I am sorry that my question might sound a little stupid, but I am
wondering what is wrong with plain old "map.resources" ?

I think that it should be enough for all the REST stuffs, or am I missing
something?

Josh Nichols

unread,
Aug 4, 2009, 9:18:02 PM8/4/09
to boston-r...@googlegroups.com
map.resources just sets up the routes for a restful controller, it
does nothing about the controller implementation.

That is what this battle is about.

- Josh

Dan Croak

unread,
Aug 5, 2009, 11:49:17 AM8/5/09
to boston-r...@googlegroups.com
Another resource to like inherited_resources:

Some its code has historically ended up in Rails core.

respond_to and respond_with:

http://www.loudthinking.com/posts/37-bringing-merbs-providesdisplay-into-rails-3
http://github.com/rails/rails/commit/09de34ca56598ae5d0302a14715b2a11b6cc9845

--
Dan Croak
@Croaky

Tom Cocca

unread,
Aug 5, 2009, 4:13:54 PM8/5/09
to boston-r...@googlegroups.com
Does anybody have any experience with make_resourceful?

http://github.com/hcatlin/make_resourceful

Another of the restful controller abstractions.  If not maybe worth checking this one out as well.  I may try and take a stab at it on the boston_rb site just for comparison.

~ Tom

Jacob Burkhart

unread,
Aug 5, 2009, 4:21:19 PM8/5/09
to boston-r...@googlegroups.com
Tom... yes I was gonna chime in with "how about make_resourceful and
resourceful_views" But then I came to the realization that I'd need
my own fork of bostonrb to properly demonstrate... and the weight of
that effort discouraged me. But now that you've brought it up....

I had previously built my own little demo app that sorta compares:
- make_resourceful
- resource_controller
- resource_this
- resources_controller

all with the goal of showing how resourceful_views can be integrated into each

it's at:
http://github.com/jacobo/resourceful_views_demo_app

ni...@hanoian.com

unread,
Aug 5, 2009, 11:26:27 PM8/5/09
to boston-r...@googlegroups.com
Hi Josh,
Thank you for the clarification.

Nonetheless, please forgive my ignorance, but the other things sound to me
like EJB, which promises that JEE developers never have to write
boilerplate code for some stuffs. But it turns out that they have to write
5 different things instead, and Repeat Themselves all over those 5 things
:)

Is it the same with certain stuffs in Rails?

Thanks.

Josh Nichols

unread,
Aug 13, 2009, 12:02:25 PM8/13/09
to boston-r...@googlegroups.com
Whoops, forgot my opinion was marinating...

I think there's probably 3 ways you'll typically change a restful controller:

 * how objects are built/created/found (ie Post.find(:all) vs current_user.posts
 * setting flash message
 * setting where an action redirects to.


== how objects are built/created/found (ie Post.find(:all) vs current_user.posts

inherited_resources and resource_controller use the same technique, overriding a method to give the 'top of the chain', so it's a draw

== setting flash message

resource_controller, you call class methods on your controller like:

    create.flash 'The object was created'

inherited_resources, you use the i18n framework, and fill out config/locales/en.yml with what you need. If you use the same verbage across different resources, you can also specify a generic way of doing this in the en.yml, ie "{{resource_name}} created."

== setting where an action redirects to.

resource controller, you call class methods on the controller like:

    create.wants.html { redirect_to root_url }

For inherited_resources, there's a couple of ways, but the shorthand version is like:

   def create
     create! { redirect_to root_url }
  end

== verdict

Using internationalization is definitely a win for inherited_resources.

I generally found the way you progress from boiler plate to customized actions to feel a bit nicer, natural, etc in inherited_resources:

   - start with the config/locales/en.yml for flash
   - use create! if you need to do something before/after the boiler plate
   - use create! { # render or redirect here } if you just need to change the redirect
   - use create! {|format|  } if you need finer control over what happens during respond_to in the happy path
   - use create! {|success, failure| } to have control over the respond_to for both the happy and sad path
   - just implement your own create

This is a series of steps I've internalized just from using inherited_resources on this project. For resource_controller, I usually have to refer back to the README or source to figure out how I'm supposed to use it for a particular situation.

So given this, I'd be inclined to use inheited_resources over resource_controller.

- Josh

On Tue, Aug 4, 2009 at 8:56 PM, Dan Croak <dcr...@thoughtbot.com> wrote:

Dan Pickett

unread,
Aug 13, 2009, 12:25:16 PM8/13/09
to Boston Ruby Group
I considered myself an avid fan of resource_controller until I saw
inherited_resources. As a quick test this week, I moved a few
controllers over from RC to IC, and found that the syntax was much
more natural. Writing controllers w/ Resource Controller always seemed
like another layer of complexity on top of ActionController.

I like that responds_with is going into core - hopefully more pieces
of IC will be introduced into core with time.

Josh Clayton

unread,
Aug 13, 2009, 1:11:09 PM8/13/09
to Boston Ruby Group
I've yet to try inherited_resources, but I've been using
resource_controller for a while so I'll comment on what I like/don't
like about it.

RC is great if you're using boilerplate code. Changing flash styles
requires redefining it for every action, so IR definitely wins here.
I was skeptical of this at first because I don't typically care about
i18n. However, being able to define "defaults" for each type of
action is very appealing since I typically override them anyway.

Looking at RC's handling of before blocks as well as how it handles
success/failures is awesome. I prefer this to IR and love how concise
it is. It helps keep your controllers clean and small (even 1 line vs
5 is a win for me, and it feels easier to grok). Calling super with a
block or that action as a bang method with a block just feels really
confusing and repetitive to me.

I love that pieces of IR are getting integrated into Rails 3. This is
a big win regardless of the RESTful plugin you use.

All in all, I'm for RC because of how concisely it handles before/
after/success/failure. Once Rails 3 hits, though, I think it'll be
anybody's game.
Reply all
Reply to author
Forward
0 new messages