A small shop I’ve been writing for for fathers pharmacy was a welcome playground for modeling my domain RESTful. During my ventures, two big issues had me thinking quite hard for a while and there’s still no proper solution available. One of them was a DRY implementation of controllers for nested resources which I’ll describe later, the other one was the outdated inplace editor plugin in Rails.
In-Place editing RESTful resources
Writing applications in REST-style encourages an even stricter separation of view and controller logic than the usual Rails’ stack. A key principle is that the client alone should provide the user means to manipulate and PUT/POST data to the server. This is easier said than done in current browsers and with the HTML format (which just wasn’t made for building GUIs, but that’s a topic for another post). AJAX is the closest we can come to this ideal, enabling a seamless transition from a plain view of a resource to a editable form without going through too much pain.
A widely used way to achieve these transitions are inplace editors, made popular by Flickr and supported through nice helper methods in rails. The probem now is that these helper methods were written around, or even before Rails 1.0 with not the slightest hint of REST in them. Planting in_place_edit_for :object, :attribute
in your controller creates a set_object_attribute
action that finds an object by id, updates only attribute
and renders attribute
s new value as a plain, short string to the client. The client, in this case the XMLHttpRequest, takes that response and puts it in the appropriate place in the HTML document.
There are several problems with this approach:
- The generated actions are extremely simple and devoid of any form of sophisticated flow control (authorization, exception handling)
- The generated actions perform a task that can be done in the good old
update
action and are thusly redundant. - Those new actions aren’t at all RESTful.
- Ideally, no special server side code should be necessary.
While problem 1 can be easily countered by implementing your own version of in_place_edit_for
, the real point are the other issues. The update
action already performs the task of updating one or more attributes and is equipped with whatever authorization checks are necessary (does object belong to the logged in user?). The update
action corresponds to the REST-verb POST
and doesn’t violate REST principles.
A solution that solves all these problems would have to look like this (client-side Javascript only):
- The inplace editor posts to the objects url (something like
/object/123
), passing the attribute to be updated as a HTTP parameter. - The server sends a response when the update is completed successfully or unsuccessfully.
- In case of an unsuccessful update some form of status could be transferred in the response
- In case of a successful update, the server doesn’t send the updated attributes value, instead the client should GET the object requesting a text/json content-type, extract the desired attribute from the json and update the HTML with its value.
I already tried building my own inplace editor Javascript helper but since much of the functionality of the rails inplace editor depends on the the editor defined in script.aculo.us I gave up. On the one hand the problem wasn’t so pressing that I could justify spending a weekend digging through the source, on the other hand I’d really like to see a good jQuery integration in rails and think maybe I could hit two birds with one stone if I try to go this direction one day.