param to url mapping

I'm currently reading "Agile Web Development with Rails (2nd Edition)"
and I've run into something I don't quite understand.

In one section of the book they have link in the one of the views that
looks like this:

<%= link_to 'Show', :action => 'show', id: => product %>

This produces a link similar to the following:

http://www.example.com/product/show/1

I understand that product is the controller, show is the action and 1
is the product id.

Then in the show action of the product controller you would use
something like this to access the products id:

product = Product.find(params[:id])

What I don't understand is how Rails is mapping 1 in the url I gave
above to params[:id].

What if I had something a little more complicated like categories for
products. Products might be able to fit into many different categories
so I have a controller called ProductCategories. I have a list action
which will list all the products for a given category.

A link like this may be

<%= link_to "category.name", :action => 'list', :id => category %>

which I think will produce the following URL:

http://www.example.com/product_categories/list/1

That's straight forward. But what if a list of products in a category
is long and I want to be able to sort the order by say price
(ascending or decending) or name (ascending or descending).

Could I have links like the following:

<%= link_to 'By Price', :action => 'list', id: => category, :sort_by
=> 'price', :sort_direction => 'asec' %>

That the above link look like this:

http://www.example.com/product_category/list/1/price/asec

and if so how is Rails mapping the URL to params?

I hope that make sense.

Eric Stewart
ericleestewart@gmail.com

ericleestewart@gmail.com wrote:

I'm currently reading "Agile Web Development with Rails (2nd Edition)"
and I've run into something I don't quite understand.

In one section of the book they have link in the one of the views that
looks like this:

<%= link_to 'Show', :action => 'show', id: => product %>

This produces a link similar to the following:

http://www.example.com/product/show/1

I understand that product is the controller, show is the action and 1
is the product id.

Then in the show action of the product controller you would use
something like this to access the products id:

product = Product.find(params[:id])

What I don't understand is how Rails is mapping 1 in the url I gave
above to params[:id].

What if I had something a little more complicated like categories for
products. Products might be able to fit into many different categories
so I have a controller called ProductCategories. I have a list action
which will list all the products for a given category.

A link like this may be

<%= link_to "category.name", :action => 'list', :id => category %>

which I think will produce the following URL:

http://www.example.com/product_categories/list/1

That's straight forward. But what if a list of products in a category
is long and I want to be able to sort the order by say price
(ascending or decending) or name (ascending or descending).

Could I have links like the following:

<%= link_to 'By Price', :action => 'list', id: => category, :sort_by
=> 'price', :sort_direction => 'asec' %>

That the above link look like this:

http://www.example.com/product_category/list/1/price/asec

and if so how is Rails mapping the URL to params?

I hope that make sense.

The key is to look in routes.rb. There is where the symbols are mapped to what will eventually end up in params.

E.g. if you look at the bottom of your routes.rb you should see something like:

map.connect ':controller/:action/:id'

That ":id" is where the params[:id] is coming from. If you change that line to, say:

map.connect ':controller/:action/:article_num'

Then params[:id] will be nil and you'll need to use params[:article_num] to get that path element from the URL.

You can added whatever "named" path elements that you like in your routes and those symbols will be accessible in params. E.g.:

map.connect '/:year/:month/:day', :controller => "date"

will give you:

params[:year]
params[:month]
params[:day]

If you build a URL with a symbol that isn't in the route it'll get tacked on as a URL query parameter. So if do something like:

link_to "query url", :controller => "cont", :action => "act", :id => "blah", :whatever => "random"

you'll get:

cont/act/blah?whatever=random

and the value of whatever will be in params[:whatever]