# "Ugly URLs" don't work with resources?

**URL:** <https://www.ruby-forum.com/t/ugly-urls-dont-work-with-resources/88803>\
**Category:** Rails\
**Created:** [March 14, 2007, 3:31pm UTC](https://www.ruby-forum.com/t/ugly-urls-dont-work-with-resources/88803 "2007-03-14T15:31:16Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![maciek](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b487fb/32.png) [@maciek](https://www.ruby-forum.com/u/maciek)\
**Post date:** [March 14, 2007, 3:31pm UTC](https://www.ruby-forum.com/t/ugly-urls-dont-work-with-resources/88803/1 "2007-03-14T15:31:16Z")

</div>

I’ve a Course model in my application and so my routes file contains  
the standard:

map.resources :courses

and then of course:

map.connect ‘:controller/:action/:id.:format’  
map.connect ‘:controller/:action/:id’

URLs like “[www.example.com/courses/1;edit](http://www.example.com/courses/1;edit)” and “[www.example.com/](http://www.example.com/)  
courses/edit/1” work fine, but when I use something like this  
“[www.example.com/courses/edit?id=1](http://www.example.com/courses/edit?id=1)” it doesn’t work. The “show” action  
is called instead of “edit”. Removing map.resources line fixes it of  
course, but I was wondering if there’s a way to have the cake and eat  
it too?

I need the “[www.example.com/courses/edit?id=1](http://www.example.com/courses/edit?id=1)” format to be able to  
send a GET request through a form with a select\_tag setting an id. So  
I’d like to do something like this:

Edit course  
\<% form\_for(:course, :url =\> {:controller =\> ‘courses’, :action =\>  
‘edit’},  
:html =\> { :method =\> :get }) do |f| %\>  
\<%= select\_tag ‘id’,  
options\_from\_collection\_for\_select(Course.find(:all), ‘id’,  
‘name\_and\_dates’) %\>  
\<%= submit\_tag ‘Go!’ %\>  
\<% end -%\>

So, alternatively, is there any other way to do this (and make it  
degradable to non-JS browsers)?

Thanks,  
Maciek

---

<div class="post-metadata">

**Author:** ![maciek](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b487fb/32.png) [@maciek](https://www.ruby-forum.com/u/maciek)\
**Post date:** [March 15, 2007, 1:18am UTC](https://www.ruby-forum.com/t/ugly-urls-dont-work-with-resources/88803/2 "2007-03-15T01:18:44Z")

</div>

On 3/14/07, Maciek [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> URLs like “[www.example.com/courses/1;edit](http://www.example.com/courses/1;edit)” and “[www.example.com/](http://www.example.com/)  
> courses/edit/1” work fine, but when I use something like this  
> “[www.example.com/courses/edit?id=1](http://www.example.com/courses/edit?id=1)” it doesn’t work. The “show” action  
> is called instead of “edit”. Removing map.resources line fixes it of  
> course, but I was wondering if there’s a way to have the cake and eat  
> it too?
> 
> I need the “[www.example.com/courses/edit?id=1](http://www.example.com/courses/edit?id=1)” format to be able to  
> send a GET request through a form with a select\_tag setting an id. So  
> I’d like to do something like this:

Routes match top to bottom. By putting map.resources above the  
generic resource route, it matches /courses/edit as /courses/:id. Try  
this:

map.connect ‘:controller/:action/:id’, :action =\> /[a-z]+/, :id =\> nil

# matches /foo/list or /foo/show/1

map.resources …  
…

–  
Rick O.  
[http://lighthouseapp.com](http://lighthouseapp.com)  
[http://weblog.techno-weenie.net](http://weblog.techno-weenie.net)  
[http://mephistoblog.com](http://mephistoblog.com)

---

<div class="post-metadata">

**Author:** ![maciek](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b487fb/32.png) [@maciek](https://www.ruby-forum.com/u/maciek)\
**Post date:** [March 15, 2007, 12:04pm UTC](https://www.ruby-forum.com/t/ugly-urls-dont-work-with-resources/88803/3 "2007-03-15T12:04:18Z")

</div>

Rick O. wrote:

> map.connect ‘:controller/:action/:id’, :action =\> /[a-z]+/, :id =\> nil
> 
> # matches /foo/list or /foo/show/1
> 
> map.resources …

Thanks Rick. I added \_ to the pattern for some actions to work, but this  
works pefectly.

Trevor,

Do you think doing this that way might get me into trouble later? Are  
there any particular risks?

Thanks,  
Maciek.

---

<div class="post-metadata">

**Author:** ![maciek](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b487fb/32.png) [@maciek](https://www.ruby-forum.com/u/maciek)\
**Post date:** [March 15, 2007, 2:00am UTC](https://www.ruby-forum.com/t/ugly-urls-dont-work-with-resources/88803/4 "2007-03-15T02:00:47Z")

</div>

Hey,

Personally, and assuming this is an isolated case for you, I’d avoid  
tinkering with routes like Rick suggests.

In your routes.rb:

map.resources :courses, :collection =\> {:edit\_for =\> :get}

In courses\_controller.rb:

def edit\_for

# personally, I’d just do redirect\_to(edit\_course\_path(params[:id]))

# but if the extra round-trip offends you…

edit  
render :action =\> :edit  
end

And finally your url helper looks like this:

edit\_for\_courses\_path(:id =\> 23) #=\> /courses;edit\_for?id=23

which is recognized by rails routing, even if you remove the default  
routes from routes.rb

HTH,  
Trevor

---

<div class="post-metadata">

**Author:** ![maciek](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b487fb/32.png) [@maciek](https://www.ruby-forum.com/u/maciek)\
**Post date:** [March 15, 2007, 4:44pm UTC](https://www.ruby-forum.com/t/ugly-urls-dont-work-with-resources/88803/5 "2007-03-15T16:44:45Z")

</div>

Heh. Isn’t

map.resources :courses, :collection =\> {:edit\_for =\> :get}

still tinkering with routes? 😉

RSL

---

<div class="post-metadata">

**Author:** ![maciek](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b487fb/32.png) [@maciek](https://www.ruby-forum.com/u/maciek)\
**Post date:** [March 15, 2007, 5:19pm UTC](https://www.ruby-forum.com/t/ugly-urls-dont-work-with-resources/88803/6 "2007-03-15T17:19:54Z")

</div>

Hey again,

as I said, “assuming this is an isolated case for you”, as in, if you  
just wanted the behavior for a particular controller and action then  
I’d deal with that specific issue rather than change route  
recognition order. The fact that you had to add ‘\_’ to the pattern  
indicates that you had more than just the ‘edit’ action in mind so  
it’s probably not an isolated case.

There’s nothing that’s specifically going to get you into trouble  
later, there are plenty of pre1.2 rails apps out there that use the  
default route just fine.

My personal experience has been that things are easier to control if  
I don’t mix resources style urls with the default route - so lately  
I’ve been _deleting_ the default route on my new projects and only  
using resources and named routes.

However, if Rick’s suggestion works for you and it doesn’t have any  
side effects that you don’t like, then you’re done 🙂

Regards,  
Trevor

---

<div class="post-metadata">

**Author:** ![maciek](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b487fb/32.png) [@maciek](https://www.ruby-forum.com/u/maciek)\
**Post date:** [March 16, 2007, 8:03am UTC](https://www.ruby-forum.com/t/ugly-urls-dont-work-with-resources/88803/7 "2007-03-16T08:03:30Z")

</div>

> My personal experience has been that things are easier to control if  
> I don’t mix resources style urls with the default route - so lately  
> I’ve been _deleting_ the default route on my new projects and only  
> using resources and named routes.

I do this too to keep things consistent. However, sometimes I’m a  
stickler for routes and I have custom routes on top of my resource  
routes. It really depends on what I’m trying to do. If in doubt, set  
up some good routing tests using assert\_routing.

–  
Rick O.  
[http://lighthouseapp.com](http://lighthouseapp.com)  
[http://weblog.techno-weenie.net](http://weblog.techno-weenie.net)  
[http://mephistoblog.com](http://mephistoblog.com)
