"Ugly URLs" don't work with resources?

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” and “www.example.com/
courses/edit/1” work fine, but when I use something like this
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” 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

On 3/14/07, Maciek [email protected] wrote:

URLs like “www.example.com/courses/1;edit” and “www.example.com/
courses/edit/1” work fine, but when I use something like this
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” 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://weblog.techno-weenie.net
http://mephistoblog.com

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.

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

Heh. Isn’t

map.resources :courses, :collection => {:edit_for => :get}

still tinkering with routes? :wink:

RSL

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 :slight_smile:

Regards,
Trevor

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://weblog.techno-weenie.net
http://mephistoblog.com