Mapping urls

I’ve been reading everything about routes but I can’t seem to make
this work…

I have a projects controller and my projects table contains id and
name fields

I want to be able to navigate to myurl.com/projects/“name” instead of
the default method or /projects/“id”

Seems like this should be pretty basic but I haven’t been able to get
it to work.

Appreciate the help.

Im having similar problems.

Im a total newbie and cant really understand how routes.rb generates
default routes and paths in rails2.0.

EG:

<td><%= link_to 'Show', user_path(user) %></td>
<td><%= link_to 'Edit', edit_user_path(user) %></td>
<td><%= link_to 'Destroy', user, :confirm => 'Are you sure?', 

:method => :delete %>

Seems to render paths like this in my index

/appname/users/ for Show
/appname/users//edit/ for Edit
/appname/users/ for Destroy

What do I have to do to get things like user_path(user),
edit_user_path(user), etc to render properly?

Dale C. wrote:

Should have said I have the following in my routes.rb file already

ActionController::Routing::Routes.draw do |map|
map.resources :users

map.users ‘users’, :controller => “users”, :action => “index”
map.show_user ‘user/:id’, :controller => “users”, :action => “show”
map.edit_user ‘user/:id/edit’, :controller => “users”, :action =>
“edit”

end

Am I missing something stupid?
@Dale:

As an exercise for the reader, comment your three map statements in
routes.rb, then run a rake routes (I usually route that output to a file
for easier reading). At first glance, you shouldn’t need any of your
custom maps.

@polomasta: You need to read up on how Rails does its route matching…

maybe it’s as easy as changing the controller code to check if the :id
parameter is an int, perform a Project.find(:params[:id]), otherwise
give the name based search a go Project.find_by_name(params[:id]) <-
doesn’t really matter what the param is called

Should have said I have the following in my routes.rb file already

ActionController::Routing::Routes.draw do |map|
map.resources :users

map.users ‘users’, :controller => “users”, :action => “index”
map.show_user ‘user/:id’, :controller => “users”, :action => “show”
map.edit_user ‘user/:id/edit’, :controller => “users”, :action =>
“edit”

end

Am I missing something stupid?

@Dale:

As an exercise for the reader, comment your three map statements in
routes.rb, then run a rake routes (I usually route that output to a file
for easier reading). At first glance, you shouldn’t need any of your
custom maps.

Ok so on removing my custom map routes and raking I get the following:

(in /home/webbie/peoplesearch)
users GET /users
{:controller=>“users”, :action=>“index”}
formatted_users GET /users.:format
{:controller=>“users”, :action=>“index”}
POST /users
{:controller=>“users”, :action=>“create”}
POST /users.:format
{:controller=>“users”, :action=>“create”}
new_user GET /users/new
{:controller=>“users”, :action=>“new”}
formatted_new_user GET /users/new.:format
{:controller=>“users”, :action=>“new”}
edit_user GET /users/:id/edit
{:controller=>“users”, :action=>“edit”}
formatted_edit_user GET /users/:id/edit.:format
{:controller=>“users”, :action=>“edit”}
user GET /users/:id
{:controller=>“users”, :action=>“show”}
formatted_user GET /users/:id.:format
{:controller=>“users”, :action=>“show”}
PUT /users/:id
{:controller=>“users”, :action=>“update”}
PUT /users/:id.:format
{:controller=>“users”, :action=>“update”}
DELETE /users/:id
{:controller=>“users”, :action=>“destroy”}
DELETE /users/:id.:format
{:controller=>“users”, :action=>“destroy”}

This looks ok to me (Like that means anything :slight_smile: ) but It still renders
the routes in exactly the same fashion.

user_path(user) and edit_user_path(user) both appear to render nothing
at all. Rather than /appname/id_no/ and /appname/id_no/edit/

Is there perhaps something I need to set up in another config file.
Annoyingly most of the documentation out there appears to be for rails
1.2 and not 2.0 :frowning:

Hmm… could you post your index.html.erb (or whatever) code?

Ar Chron wrote:

Hmm… could you post your index.html.erb (or whatever) code?

Ok sure index.html.erb is

Listing users

<% for user in @users %>

<td><%= link_to 'Show', user_path(user) %></td>
<td><%= link_to 'Edit', edit_user_path(user) %></td>
<td><%= link_to 'Destroy', user, :confirm => 'Are you sure?', 

:method => :delete %>

<% end %>
<%= h user.ID %> <%= h user.SurName %> <%= h user.ForeName %> <%= h user.Title %> <%= h user.RoomNo %> <%= h user.PhoneNo %> <%= h user.EMail %>

<%= link_to ‘New user’, new_user_path %>

Ar Chron wrote:

<%= link_to ‘Show’, :controller => ‘users’, :action => ‘show’, :id =>
user.id %>

Interestingly if I put that code in, the page fails as user.id doesn’t
exist, I think I’ve messed something up in the initial app set-up with
my “./script/generate scaffold Users” command.

I shall delete the app and start again from scratch I think.

Thanks for the help so far though.

Dang… that looks pretty vanilla to me. What about the page source
from the browser? edit_user_path and user_path are just helpers that
create the href’s… and should be equivalent to you typing in something
like:

<%= link_to ‘Show’, :controller => ‘users’, :action => ‘show’, :id =>
user.id %>

in your view code.

Any chance that you have a borked install of Rails? I might try an
update of Rails to see if it cleared up the issue.

Got it! I knew it would be really simple.

Thanks for the responses

polomasta wrote:

I’ve been reading everything about routes but I can’t seem to make
this work…

I have a projects controller and my projects table contains id and
name fields

I want to be able to navigate to myurl.com/projects/“name” instead of
the default method or /projects/“id”

Seems like this should be pretty basic but I haven’t been able to get
it to work.

Appreciate the help.

The most common way to do this is to override the to_param method on
your model. When rails generates a route for a model it calls to_param
on that model object, which ends up in the :id spot on your url. By
default, this returns the id.

If you add something like this to your model, where permalink is a
database field on that model:

def to_param
permalink
end

Then when you generate routes for that model object it will look like:

/thingies/my_cool_permalink

Now you just need to change how you fetch your models. On your show
action, change the standard

@thingy = Thingy.find(params[:id])

to

@thingy = Thing.find_by_permalink(params[:id])


One last popular way to handle this a hybrid approach. If you set your
to_param method to return something like:

“#{id}-#{permalink}”

Then you url will generator like:

/thingies/123-my_cool_permalink

#controller goes back to:
Thingy.find(params[:id])

The neat thing about this approach is that the ActiveRecord will convert
your params[:id] to an integer for you. This means that
“123-my_cool_permalink” gets translated to 123 without any extra code
from you. As an added bonus, the permalink part can change to something
new, and as long as the page is accessed by the same id number the link
wont break.