make_resourceful 0.2.0

Posted November 4, 2007

After many months of development, make_resourceful version 0.2.0 is finally ready for release. We’ve now got a full set of specs (i.e. tests) and full RDoc documentation. The code is cleaner, bugs are fixed, the filesize is smaller1.

Oh, and there are new features. New, awesome features.

Installation

Before we go into the features, though, let’s talk about installing the thing.

There are actually three different ways to install it. See, we didn’t just release 0.2.0 today; we released 0.2.2 as well2.

What’s the difference? 0.2.0 is Rails 1.2.3 compatible. 0.2.2 is not.

All this really means is that 0.2.2 uses the new-style URL helpers. Instead of child_path(@parent, @child), current_object will now call parent_child_path(@parent, @child). This is compatible with the Rails 2.0 API as well.

Now then. To install version 0.2.0, do

./script/plugin install http://svn.hamptoncatlin.com/make_resourceful/tags/rel_0-2-0
mv vendor/plugin/rel_0-2-0 vendor/plugin/make_resourceful

For version 0.2.2, do

./script/plugin install http://svn.hamptoncatlin.com/make_resourceful/tags/make_resourceful

Finally, if you want to take a bit of a risk, you can install from trunk:

./script/plugin install http://svn.hamptoncatlin.com/make_resourceful/trunk
mv vendor/plugin/trunk vendor/plugin/make_resourceful

Note that, like version 0.2.2, trunk is incompatible with Rails 1.2.3 and lower versions.

New Features

I talked about publish and serialization earlier. That’s probably the most visible change, but there’s plenty of other stuff as well.

For instance, there are several handy new accessors. save_succeeded? and save_failed? return whether or not a database update, like that done by create, update, and destroy, completed successfully. plural_action? and singular_action? return whether the current action is plural, like index, or singular, like show.

There are also a bunch of new additions that aren’t glamorous, like new declarations and accessors, but are important and useful all the same. For example, in 0.2.0 all the default responses have an empty Javascript response. This means that RJS templates will work automatically without any modifications of the controller.

Another useful tweak: all the callback declarations (before, after, response_for) now allow you to easily declare the same callback for multiple events. All you have to do is pass in multiple arguments, like so:

before :show, :index do
  @page_title = "Check out my resourceful controller." 
end

Singular Resources

Thanks to an idea of Peter Baker’s, make_resourceful 0.2.0 includes support for singular resources. These are resources defined by a has_one relationship. For instance, if Person has_one Hat, you’d make a HatController rather than a HatsController.

make_resourceful would notice that the controller was singular3 because of the singular controller name (no extra code required!), and act accordingly. This means that it wouldn’t define an index action, and for current_object, it would look up Person.find(params[:person_id]).hat instead of Hat.find(params[:id]).

URL Helpers

One of the handy things that was around in m_r 0.1.0 was the URL helpers: object_path and objects_path. They automatically managed all the hassles with Rails URL generation. A single call to object_path might be equivalent to a call to child_path(@grandparent, @parent, @child).

Unfortunately, these two helpers didn’t really cover all the URLs that one might have wanted to generate. What if you wanted a URL for the new action? They also were both _path methods: they returned the path of the resource, without the domain name or protocol.

Thus, in 0.2.0, we’ve added a whole slew of other URL helpers. There’s new_object_path and edit_object_path, which return the paths to the new and edit actions, respectively. Then, for each _path helper, there’s now a _url helper, which returns the domain name as well. For instance, on this blog’s PostsController, new_object_url returns “http://nex-3.com/posts/new”.

resourceful_scaffold

make_resourceful 0.2.0 improves on more than just the API. It also comes bundled with a generator in the style of the built-in scaffold_resource generator. The syntax is even the same:

./script/generate resourceful_scaffold ResourceName attribute1:type1 attribute2:type2 ...

This generates the model, views, tests, and of course made_resourceful controller for the given resource. It works out of the box with a make_resourceful installation.

It should be noted that the views it generates are Haml, not ERB, to encourage people to make their views as beautiful as their controllers will be. Haml is awesome; if you haven’t checked it out, you should4.

Deprecations

There are a few things that we’ve decided to deprecate or outright remove in make_resourceful 0.2.0. Most of these are accessors that didn’t make sense to keep separate from the methods that used them. They’d never make sense for users to directly call. Rather than overriding them, we now reccommend that you override the method that called them.

Note that some of these were only introduced after 0.1.0 was released. However, lots of people have been using trunk anyway, so I’ll mention them anyway.

The first of these accessors we removed was current_param. This just returned params[:id] and was only called by current_object. Now if you want to change which parameter is used, just change current_object.

The same is true for model_includes. It returned an empty hash, and was supposed to be overridden to provide a value that would be passed to the :include option of current_model.find in current_objects. This was inconsistent with our general “override current_objects to customize it” policy, so we chucked it.

The last accessor we deprecated was namespace_prefix. This returned a prefix for the URL-generating methods called by object_path and friends. The accessor is actually still around, but it’s been given a more general name: url_helper_prefix. Override that instead.

Finally, we removed the associated_with declaration. We did this because

associated_with :current_user, :source => :user

could in fact be done in one line using only the pre-existing declarations:

before(:create) { current_object.user = current_user }

Contributors

According to my records, the following people contributed patches or ideas that went into 0.2.0:

  1. Cristi Balan5
  2. Tom Stuart
  3. Don Petersen6
  4. Alex Ross6
  5. James Golick
  6. Mike Ferrier
  7. Jeff Hardy
  8. Hampton Catlin
  9. Myself

The Future

So what’s on the plate for 0.3.0? Our first order of business will be to add in a patch by Jonathan Linowes that will get rid of support for deeply nested resources and add support for polymorphic nesting. See his writeup for more information.

We’ll also add a more integrated exception handling mechanism, and some sort of better way of dealing with stuff like flash messages. And then… who knows?

If you have some feature you particularly want, don’t hesitate to let us know.

1 This is pretty cool. A Subversion-less install of make_resourceful 0.2.0 is roughly 250 kilobytes. 0.1.0 was a about 1.1 megabytes. The difference is even more striking if you install from Subversion.

2 We skipped 0.2.1 because we reserve odd version numbers for development versions. That way we can tell whether someone’s running trunk or not from looking at their VERSION file.

3 You can notice, too, via the singular? and plural? helpers.

4 Full disclosure: Hampton Catlin and myself are both Haml developers. We’re totally biased. But we’re biased because Haml is awesome.

5 Cristi pretty much single-handedly tracked down an insanely annoying bug, as well as supplying various other patches. Super awesome.

6 I’d link to these folks’ websites if I knew what they were.

Don said November 04, 2007:

Congratulations! More refinement to a plugin that was already incredibly useful.

I’m especially excited about the specs, it feels more “right” than how the old tests had to work (plus that symlink in the test app always confused TextMate!). All of those deprecations make perfect sense too, I think they caused more confusion to new users than anything.

Lauro said November 04, 2007:

Great Work, I will put m_r in production

Best regards from Brazil

Rahsun McAfee said November 05, 2007:

These updates are AWE-SOME, and it just keeps getting better. Congrats to the entire M_R team.

Ben Mabey said November 05, 2007:

Great! Thanks so much for the 0.2.2 release, it was a nice surprise!

ste said November 15, 2007:

“For instance, if Person has_one Hat, you’d make a HatController rather than a HatsController.” There is a problem with this when using rails 2.0: the framework assumes that your controllers will always be named in the plural form, even for singleton resources. So if you do:

map.resources :users, :has_one => :profile

and you create a ProfileController (instead of ProfilesController), you get an “uninitialized constant ProfilesController” exception.

Nathan said November 15, 2007:

Hmm… I suppose that does mean that we can’t autodetect singletonness via the name. However, it should still be possible to do so via ActiveRecord::Reflections.

That leaves open the question, though, of what to do when Person has_one :hat but Haberdashery has_many :hats. Ideally, I suppose, /people/12/hat and /haberdasheries/297/hats should both work, but should /hats/59? I guess it probably should.

But we probably still don’t want /hats/59 to work if only Person has_one :hat. I guess the best thing would be to check if all the relations are singular or not.

Chris Vincent said November 15, 2007:

I’m really glad someone else is working on this! I’ve been working on a very similar REST controller abstraction on my own time, but this very elegant and flexible implementation does everything I was striving to do with mine and does it better. Plus, since its maintenance and continued development is out of my hands, it means I can focus on the reason I was trying to build such an abstraction in the first place, that reason being to more efficiently develop my ideas into working applications. As one of my colleagues put it, you can go one of two routes: either design frameworks or design applications. So kudos to you and everyone chipping in on this project, it will make an excellent addition to the toolsets of Rails developers everywhere!

ste said November 27, 2007:

I think there is a bug in the code for url/path helpers (url.rb). The comment for method “collection_url_prefix” says: “It’s only added if url_helper_prefix returns nil.”. But if you have a namespaced nested resource, BOTH the url_helper_prefix and the collection_url_prefix must be used to generate the correct route name. For instance, in my app I have the “admin” namespace with a “movies” controller which has_many “roles”. So, the route to display the form to add role for a movie is “new_admin_movie_role”, not “new_admin_role”. As a quick patch I have simply changed line #114 in “collection_route” from:

url_helper_prefix || collection_url_prefix

to:

url_helper_prefix + collection_url_prefix
Graham said February 02, 2008:

Just curious: how does this differ from “resource_this”? Can the two plugins be used together, or does that not make sense?

Nathan said February 02, 2008:

I’m not sure, I’ve never used resource_this. Looking briefly at the documentation, it looks like r_t might not allow as much fine-grained customization through accessor redefinition as m_r, but that’s just based on a glance.

roTuKa said May 18, 2008:

Are there any chance to see make_resourceful officially on github?

Nathan said May 18, 2008:

Possibly. When we moved Haml to GitHub, there were requests that we not do the same for make_resourceful, but as git gains more traction and more people request we move m_r, they may be overridden.

Eddie said June 06, 2008:

Is there a reason nothing uses flash.now? So when there’s an error creating something and you render instead of redirect, the flash sticks around if they decide to go to another page.

dialanco said July 01, 2008:

I am looking to a github version of make resourceful, that would be great!!!!!!!

Make your comments snazzy with Textile!