# More RESTlessness: "unbalanced" routes

**URL:** <https://www.ruby-forum.com/t/more-restlessness-unbalanced-routes/112583>\
**Category:** Rails\
**Created:** [August 21, 2007, 4:34am UTC](https://www.ruby-forum.com/t/more-restlessness-unbalanced-routes/112583 "2007-08-21T04:34:59Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![jay-levitt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/a88e57/32.png) [@jay-levitt](https://www.ruby-forum.com/u/jay-levitt)\
**Post date:** [August 21, 2007, 4:34am UTC](https://www.ruby-forum.com/t/more-restlessness-unbalanced-routes/112583/1 "2007-08-21T04:34:59Z")

</div>

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.

Is there a third way?

Jay L.

---

<div class="post-metadata">

**Author:** ![jay-levitt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/a88e57/32.png) [@jay-levitt](https://www.ruby-forum.com/u/jay-levitt)\
**Post date:** [August 21, 2007, 3:59pm UTC](https://www.ruby-forum.com/t/more-restlessness-unbalanced-routes/112583/2 "2007-08-21T15:59:34Z")

</div>

Sure. The Rails implementation of REST allows you to extend the  
RESTful routes with a similar concept to choice #2 but without  
“lying.”

Say you want a unique url that updates _only_ the contact\_info of a  
user. You can extend the user routes in routes.rb like this:

map.resources :users, :member=\>{:update\_contact\_info\_of=\>:post}

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 %\>

HTH,  
AndyV

---

<div class="post-metadata">

**Author:** ![jay-levitt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/a88e57/32.png) [@jay-levitt](https://www.ruby-forum.com/u/jay-levitt)\
**Post date:** [August 21, 2007, 9:46pm UTC](https://www.ruby-forum.com/t/more-restlessness-unbalanced-routes/112583/3 "2007-08-21T21:46:46Z")

</div>

On Aug 21, 2007, at 8:59 AM, AndyV wrote:

> 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.

Rails routing is extremely flexible. There is almost never a “has to  
go somewhere I don’t want it to” with Rails routing.

HTH,  
Michael

---

<div class="post-metadata">

**Author:** ![jay-levitt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/a88e57/32.png) [@jay-levitt](https://www.ruby-forum.com/u/jay-levitt)\
**Post date:** [September 25, 2007, 11:07pm UTC](https://www.ruby-forum.com/t/more-restlessness-unbalanced-routes/112583/4 "2007-09-25T23:07:13Z")

</div>

See below…

Michael D. Ivey wrote:

> > it’s not obvious, :member is a hash for defining actions for

You could also

map.resources :users, :collection =\> {:contact\_info =\> :put}
