resource_hacks: A Restful Plugin You’re Likely To Need
The new app I’m working on is using EdgeRails, SimplyRestful and all the rest, so I’ve been learning a lot and bumping into situations I don’t immediately know how to handle. One of those is how to access resources using arbitrary keys in the URL.
For example, let’s say you want to show all the items in your application that have been tagged with the word ‘rails’. In the purely Restful world, your URL for that would be mapped like this:
map.resource :tags
which would give a URL like this /tags/:id where :id represents the unique id of the ‘rails’ tag in the database. While that may be correct, it’s not pretty, and it’s not intuitive for users.
You could hack something together so the system still used a numeric id but appended some textual “meta-data”, as John Susser has discussed. But in my opinion, for this example even that is inadequate. What if the user decides to switch the tag in the URL from ‘rails’ to ‘ruby’? They’d also need to swith the unique id in order for things to work.
Fortunately, Jeremy Voorhis has a fix; it’s a plugin called resource_hacks, and it allows us to use any kind of key we want in the route. So now our mapping becomes:
map.resource :tags, :member_path => ‘/tags/:tag_name’
Which would give us the nice /tags/rails URL we wanted.
There’s some debate on Jeremy’s blog about whether this should get into trunk, and it looks like for now it will stay out due to a difference of opinion about whether it’s right. But it’s clearly called for in my case, so I’m going to go ahead with it.
Can anybody think of a better way of solving this problem, perhaps one that would allow both numeric and non-numeric keys in the URL?
Comments (4 comments)
ooh, looks nice.
Hopefully the rails core team will get over the numerically named resources thing.
Luke Francl / October 5th, 2006, 8:05 pm / #
It’s possible to use a non-numeric resource ID without Jeremy’s plugin. I built a system that uses tags that works just how you describe: /tags/rails gets you all the posts tagged with “rails”. I even made it work with multiple tags: /tags/rails&rest finds the posts with both tags. It’s trivial to do - just process params[:id] like a string.
As for int vs string params, just apply whatever cleverness you need to to distinguish the param type. Jamis Buck has a great example of what you can do with that, and how:
http://weblog.jamisbuck.org/2006/10/7/helping-activerecord-finders-help-you
josh susser / October 9th, 2006, 2:03 pm / #
Thanks Josh, I’ll check out that link. As for processing the params[:id] like a string, I’m not sure I like it. There are cases where I need to look for one or the other, and I could see it getting confusing…
bruno / October 9th, 2006, 2:33 pm / #
Hello! Good Site! Thanks you! adfcgtoreldlnt
jnsryyfcun / June 18th, 2007, 6:58 pm / #
Post a comment