views:

13

answers:

1

I have a Posts model with id and title columns.

I've got my route (rails 2.3.8) set up as follows:

map.post ':title/:id', :controller => 'posts', :action => 'show'

which works correctly when recognising URLs and when generating them explicitly, as in

post_url(:title => 'foo', :id => 123)

which comes out nicely as /foo/123. What I'd like is to be able to call

p = Post.create!(:title => 'foo') # let's assume it gets ID 123
url_for(p)

and get the same path out. But I get an error:

post_url failed to generate from {:action=>"show", :controller=>"posts",
    :title=>#<Post id: 123 title: "foo" created_at: ...

How do I specify that a named route should use a model's columns its _url and _path functions?

A: 

When you declare a route, the way you call it requires a certain number of parameters, and they must be specified in the correct order or things can get confused.

Here are some typical routes:

map.none '/', :controller => 'none', :action => 'index'
map.one '/:one_id', :controller => 'one', :action => 'show'
map.two '/:one_id/:two_id', :controller => 'two', :action => 'show'
map.three '/:one_id/:two_id/:three_id', :controller => 'three', :action => 'show'

When you want to call them, you need to specify the parameters you've put in the route or it will be invalid:

none_path
one_path(one)
two_path(one, two)
three_path(one, two, three)

You can include optional parameters at the end. Generally it's a bad idea to mix and match the automatic routing and the manual routing methods:

# Using named routes
one_path(one) # /one/1
one_path(one, :two_id => two) # /one/1?two_id=2
one_path(:one_id => one) # Awkward format for same

# Using automatic routing
url_for(:controller => 'one', :action => 'show', :one_id => one) # /one/1

Path parameters in brackets like (:format) are optional but these are best avoided except when there are safe defaults.

You're probably tripping up the url_for method by including two parameters in your route instead of simply :id.

tadman