I'm working on an application (on Edge Rails) that has a really long user
profile page - viewed, of course, with a GET to /users/:id.
The editing side of things needs to be broken up into four
logically-grouped screens - say, contact info, work history, education, and
personal info. These screens are essentially update-only - their "show"
counterpart is the whole profile at /users/:id. And the update can only be
performed by current_user, so the :id is superfluous.
There is no Create function, and there is no Delete function.
So far, I see only two choices:
1. Don't use RESTful routes at all. Change the GET to /users/show/:id, and
do the updates with POSTs to /users/edit_contact_info,
/users/edit_education, etc. Put it all in users_controller. This is the
path I've been taking, but it loses some of the simply_helpful magic.
2. Create RESTful routes, and manually draw them in routes.rb. This seems
brittle, and I have to lie about (e.g.) "contact_info" belonging to the
collection instead of the member, since I don't want the :id in the URL.
Plus, I think that means each of the four mini-edit pages has to go in its
own, one-action controller! Ugly.
What this says is that there should be a url for an individual user
resource (a _member_ of the users collection) with an action mapping
to "update_contact_info_of" that accepts only POST data. Just in case
it's not obvious, :member is a hash for defining actions for
individual resources, keyed by the name of an action and with a value
of the allowed http methods (:get, :put, :post, :delete, :any).
By extending the users routes in that way, the form_for that wraps the
contact info can looks like this:
<% form_for :user, update_contact_info_of_user_path(@user) do |f| %>
...
<% end %>
To me, this smells like RPC. There's a verb in your URL, "update". You don't need that, you've already said you're updating because of PUT.
What I would do is define a singleton resource for profile.
map.resource :profile
The view for that profile is broken up, I gather from the original question, into multiple forms. They can all PUT to the same reasource, though, /profile. There's nothing that says a PUT/update has to include ALL the data for the resource.
Personally, I would add extra bits onto my profile resource, so a GET of /profile/contact_info would show the view for editing the contact info and /profile/work_history would show the view for editing the work history.
Rails routing is extremely flexible. There is almost never a "has to go somewhere I don't want it to" with Rails routing.
What this says is that there should be a url for an individual user
resource (a _member_ of the users collection) with an action mapping
to "update_contact_info_of" that accepts only POST data. Just in case
it's not obvious, :member is a hash for defining actions for
individual resources, keyed by the name of an action and with a value
of the allowed http methods (:get, :put, :post, :delete, :any).
To me, this smells like RPC. There's a verb in your URL, "update".
You don't need that, you've already said you're updating because of PUT.
What I would do is define a singleton resource for profile.
map.resource :profile
The view for that profile is broken up, I gather from the original
question, into multiple forms. They can all PUT to the same
reasource, though, /profile. There's nothing that says a PUT/update
has to include ALL the data for the resource.
Personally, I would add extra bits onto my profile resource, so a GET
of /profile/contact_info would show the view for editing the contact
info and /profile/work_history would show the view for editing the
work history.