I've loving developing my web apps using RESTful design patterns. It is definately a concept shift. Rather than thinking of the URL as a way to embed programmatic calls, the URL becomes fairly static. All it does is represent the application's resources (aka our Models) and provide verbiage to modify them (POST, GET, PUT, DELETE). And that's it.
RESTful design in Rails is pretty straight forward when you only ever update data with forms, but what if you need to pass parameters via a URL? For example, let's say you want to put a link like "approve" on a page so that your HR manager can simply click a link to approve a job resume.
In old rails we could have created an action called "approve" in our resumes_controller and called that action using a URL with
http://www.website.com/resumes/approve/2.
But in RESTful development we should only be treating our URL's as resource representations, not as a way to make programmatic calls. Instead we should be calling our resume resource with a :put method.
http://www.website.com/resumes/2
Ok...yeah, we're updating the resume model, but how do we tell the app what we are specifically updating on that resource? We do this by passing parameters to that resource, in this case "status" as "approved". We would want the resulting URL to be
http://www.website.com/resumes/2?status=approved
But how do we embed these parameters RESTfully? The magic? Rails does this by accepting additional parameters via the application_path() option in our link_to tag. In this case we are going to pass the :id parameter as well as a parameter called :application which is a hash including our ":status" and "approved" parameters.
<%= link_to 'approve', application_path(:id => resume.id, :resume => {:status => "approved"}), :method => :put %>
application_path() is a rails helper that takes the options specified and generates a URL in a RESTful way. In this case it will create a URL representing the resume resource, add on the parameters we passed (:id and :status) then tack on the RESTful method, in this case 'put'.
In our resumes_controller, the update action (which corresponds to put) will be called and the resume model will be committed using the update_attributes(params[:resume]) method. update_attributes will update the model with all of the corresponding parameters, in this case "status."
Shazaam! Now isn't that clean?! No extra methods in our controllers, just the typical CRUD.
Remember, conceptually speaking we are not using our URL to make a programmatic call. RESTfully speaking we are simply 'putting' (or updating) the resource specified in our URL with the modified parameters.