(first posted: Jun 26, 2007)
(2244 Reads)
keywords: make_resourceful REST
Permalink
make_resourceful notes
"make_resourceful is a plugin that allows you to factor out all the repetitive REST code that clutters up the controller a surprising amount. It manages this by automatically creating typical RESTful actions, while allowing plenty of room for user customization."
My bet is this code will make its way into Rails core one day.
Here are some useful links:
Slides from Hampton's presentation at RailConf'07, providesa a great simple overview: http://www.hamptoncatlin.com/assets/2007/5/21/make_resourceful.pdf
This is an excellent overview of make_resourceful. Actually, its the only realy documentation I've found, other than the source code and rdocs. (Thanks Nathan!) Overview of 0.1.0: http://nex3.leeweiz.net/posts/7
This is Hampton's home page which actually doesnt say much about make_resourceful http://hamptoncatlin.com
Here's the SVN trunk: http://svn.hamptoncatlin.com/make_resourceful/trunk
Cool Named URLs
make_resourceful has a bunch of handy named url's that are not exposed as helper methods by default. But I've been using them by adding this to application.rb
helper_method(:object_path, :objects_path, :new_object_path, :edit_object_path)
Examples:
<%= link_to 'New item', new_object_path %>
<%= link_to 'Show', object_path(item) %>
<%= link_to 'Edit', edit_object_path(item) %>
edit:
form_for(current_object, :url => object_path)
new:
form_for(current_object, :url => objects_path)
Caveats
OK, so make_resourceful is the greatest thing since sliced bread. Well, almost. Problems start to creep up on nested resources. And it doesnt support polymorphic models at all.
has_one associations
make_resourceful works fine when your model has_many :things, but it breaks when it has_one :thing
In this case i get
undefined method `things' for #<Article:0x31be538>
because its looking for the pluralized model name as the parent's accessor, and assumes that accessor is a model class (eg it tries to call parent.things.find(id) to get the scoped current_object rather than simply, parent.thing).
I tried to work through a patch or workaround but it started to touch too much of the existing library.
singleton resource routes
since has_one associations aren't supported, it make sense neither are nested singleton routes, using map.resource (versu map.resource), or the :has_one declaration in Edge). I mention it because its possible to support the former without the latter.
Polymorphic models
Controllers for polymorphic models are not supported. Polymorphic models are ones declared with something like Comment model belongs_to :commentable, :polymorphic => true , and then in the Article model, you say, has_many :comments, :as => :commentable .
Actually make_resourceful is fine as long as you only use the model with one parent. Which of course defeats the purpose of making it polymorphic in the first place. This is because the current code assumes the controller can be nested below just one parent.
Parent controllers that use different model names
m_r assumes that the model resource for a controller is the same name as in the controller. That is, ThingsController assumes Thing model. If the controller references a different model name, you can change it by redefining current_model, as in ThingsController,
def current_model
Other
end
But in a nested resource, if the parent controller has a different model than the controller name implies m_r won't find it, it assumes the name relationship.
Suppose you have a controller CarsController that actually references Auto model, and there is no Car model. Thus, when you do "/cars/1/parts/2" and have PartsController:
make_resourceful do
belongs_to :auto
you get an error you get an error (0 id in Car.find) since there is no param[:car_id]. But if instead you try:
belongs_to :car
you get an error "uninitialized constant Car" (as load_parent_objects tries to find a model named Car)
My workaround is to fake out m_r by providing the param it wants, e.g.
before_filter :get_parent_param
def get_parent_param
param[:auto_id] ||= param[:car_id]
end
There are no comments attached to this item.



