views:

147

answers:

3

I created model objects of from generating a scaffold, but now I want to instead of linking to
/:controller/:id (/objectname/1) to /:controller/:title (/objectname/new_blog_post). How do I do this so that links will correct link to the title and not id?

I want to go from:

/:controller/:id

to

/:controller/:name
A: 

Write a custom route.

Robert Elwell
+1  A: 

You will need to change a few things:

You'll have to pass the title attribute to any paths/urls when you do stuff like link_to e.g.

post_path(@post)

will become

post_path(@post.title)

You'll also have to update your finds to look for posts by title, as opposed to id e.g.

@post = Post.find(params[:id])

will become

@post = Post.find_by_title(params[:title])

That should get you started :). You'll obviously want to slug the title and validate the uniqueness of the title as well.

EDIT: After reading Robert Elwell's answer, maybe I misunderstood the question. Do you already have a route like you described for a specific object, or are you doing this with the 'basic' routes? If the latter, you're much better off writing a custom route like Robert suggests, and then doing some of the stuff I suggested.

theIV
+2  A: 

Use to param

class User < ActiveRecord::Base

  def to_param
    name.blank? ? id : name
  end

end

Or look into a plugin, acts_as_sluggable and friendly_id are ones I know of.

EDIT: Oh yes and as mentioned make sure whatever you use is unique.

EDIT:

it would work like:

class UsersController < ActionController::Base

  def index
    @users = User.all
  end

end

In view:

<% @users.each do |user| %>
  <%= link_to user.name, user_path(@user.id) %>
<% end %>

And if the that users name is John then it will render /users/John after you click that link

railsninja
+1 You know, I've never overridden `to_param`. Maybe I should start doing that.
theIV
Actually, looking at that again, would that be a good idea? If name were blank, what would his finds look like in the controller?
theIV
It is still find with an id, the blank check it to put the id as the url if there is no name. It's untested but it demonstrates a basic idea for it.
railsninja
I guess my point was more directed at if he were to do something like what you suggested above, he should at least validate the presence of a name, rendering the id part useless because his finds will be `find_by_name` as opposed to just `find`. Or am I mistaken?
theIV
You still find by id. It just renders a name as the url for that object if the name exists, otherwise it uses the id as normal.
railsninja
I had not understood that. That's awesome, thanks for the tip.
theIV
How to you find by id if you can only have the name from the request url?IMO the best option is to have a separate field for the slug.
Leonid Shevtsov