# Controller methods and how I learned to love 'rake routes'

**URL:** <https://www.ruby-forum.com/t/controller-methods-and-how-i-learned-to-love-rake-routes/187885>\
**Category:** Rails\
**Created:** [April 30, 2010, 9:57pm UTC](https://www.ruby-forum.com/t/controller-methods-and-how-i-learned-to-love-rake-routes/187885 "2010-04-30T21:57:04Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![fearless\_fool](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/5e9695/32.png) [@fearless\_fool](https://www.ruby-forum.com/u/fearless_fool)\
**Post date:** [April 30, 2010, 9:57pm UTC](https://www.ruby-forum.com/t/controller-methods-and-how-i-learned-to-love-rake-routes/187885/1 "2010-04-30T21:57:04Z")

</div>

Face it: to the newcomer, Rails routing is strange and mysterious. It  
took me a while get the hang of it, so I thought I’d share some info  
(and a couple of handy techniques) for those who are new to Rails.

Here, assume we have Users and Reports, and that one User “has many”  
Reports. Normally, that will be expressed in your model files (but  
that’s another topic!) – but right now we’re focused on making an entry  
in config/routes.rb to express how incoming URLs map to your  
controllers.

In this example, we’re using RESTful routing to create “shallow nested  
routes” to express that a User :has\_many Reports. So we create an entry  
in config/routes.rb like this:

# ====== config/routes.rb: map.resources :users, :has\_many =\> :reports, :shallow =\> true

Assuming we already have a controller for User, we still need a  
controller for Reports. Go ahead and type “rake routes” in a shell  
window to see what the routing system generated. Here are the relevant  
lines for the Reports controller:

# ====== % rake routes … user\_reports GET /users/:user\_id/reports {:controller=\>“reports”, :action=\>“index”} POST /users/:user\_id/reports {:controller=\>“reports”, :action=\>“create”} new\_user\_report GET /users/:user\_id/reports/new {:controller=\>“reports”, :action=\>“new”} edit\_report GET /reports/:id/edit {:controller=\>“reports”, :action=\>“edit”} report GET /reports/:id {:controller=\>“reports”, :action=\>“show”} PUT /reports/:id {:controller=\>“reports”, :action=\>“update”} DELETE /reports/:id {:controller=\>“reports”, :action=\>“destroy”} …

Though it may not be immediately obvious, each line tells us two things:  
which URL will be matched to method in the Reports controller, and a  
‘helper function’ you can use to generate that URL.

The leftmost column is the name of the helper functions that have been  
created for you, but stripped of \_url or \_path, so ‘user\_reports’  
signifies ‘user\_reports\_url(user\_id)’ (the fully qualified url) or  
‘user\_repors\_path(user\_id)’ (the abbreviated path).

The next column is the HTTP method (GET, POST, PUT, DELETE).

The third column is the path template that the routing system matches  
against: the incoming URL must have this form to be a match.

And the last column is the controller and method within the controller  
that gets called for that method/template combination.

# Handy technique 1:

To better understand those generated helper functions, launch a console.  
Within the console, you can test the helper functions using  
‘app.\<helper\_fn\>’ like this:

======  
bash-3.2$ script/console  
Loading development environment (Rails 2.3.5)

> > app.user\_reports\_path(10)  
> > =\> “/users/10/reports”  
> > app.user\_reports\_url(10)  
> > =\> “[http://www.example.com/users/10/reports](http://www.example.com/users/10/reports)”  
> > app.new\_user\_report\_path(10)  
> > =\> “/users/10/reports/new”  
> > app.edit\_report\_url(33)  
> > =\> “[http://www.example.com/reports/33/edit](http://www.example.com/reports/33/edit)”  
> > app.report\_path(33)  
> > =\> “/reports/33”  
> > ======

# Handy technique 2:

Since I haven’t been writing Rails code very long I can’t keep all these  
routes, parameters and helper functions straight in my mind. So the  
first thing I do is stub out a skeleton ReportsController and annotate  
with comments lifted from ‘rake routes’.

Here’s what my skeleton ReportsController might look like – the comment  
before each method documents the helper function that will generate the  
HTTP call to get you to that method, and what to look for in your  
params[] hash.

If you look at the comments, the relationship to the output of rake  
routes should be obvious. (It would be great if ‘script/generate  
controller’ added these comments for your automatically! That will be a  
future project unless someone beats me to it…)

====== file: app/controllers/reports\_controller.rb  
class ReportsController \< ApplicationController

# arrive here via ‘GET user\_reports\_{url|path}(user\_id)’

# url has the form ‘/users/:user\_id/reports’

def index  
end

# arrive here via ‘POST user\_reports\_{url|path}(user\_id)’

# url has the form ‘/users/:user\_id/reports’

def create  
end

# arrive here via ‘GET new\_user\_report\_{url|path}(user\_id)’

# url has the form ‘/users/:user\_id/reports/new’

def new  
end

# arrive here via ‘GET edit\_report\_{url|path}(id)’

# url has the form ‘/reports/:id/edit’

def edit  
end

# arrive here via ‘GET report\_{url|path}(id)’

# url has the form ‘/reports/:id’

def show  
end

# arrive here via ‘PUT report\_{url|path}(id)’

# url has the form ‘/reports/:id’

def update  
end

# arrive here via ‘DELETE report\_{url|path}(id)’

# url has the form ‘/reports/:id’

# def destroy end end

So now, you can fill out your code knowing what you’ll find in the  
params hash when a method is called, and which helper function will  
generate an HTTP call to each method within your controller.

Hope this helps.

- ff
