6

How can I amend the routing from http://localhost:3000/profiles/1 to http://localhost:3000/myusername ?

I have a Profile model with the following table:

def self.up
    create_table :profiles do |t|
      t.string :username
      t.text :interest

      t.timestamps
    end
 end

And my routes.rb file:

  resources :profiles

I have looked at similar answers dealing with to_param, devise or nested loops or even an example in Rails 2.3, but i couldn't find a way that works.

What changes should I make to the profile/view/show.html.erb, routes.rb and model/profile.rb (if any) to amend the routing from http://localhost:3000/profiles/1 to http://localhost:3000/username? I'm learning from the basics, hence I rather not use any gems or plugins.

Patrick Mevzek
  • 10,995
  • 16
  • 38
  • 54
Sayanee
  • 4,957
  • 4
  • 29
  • 35

2 Answers2

4

If you want use usernames instead of IDs try friendly_id gem.

If you want to do it by yourself, the easiest way is to override method to_param in our model to return username, and then search in your controller by username.

In model:

def to_param
  username
end

In controller:

def show
  @user = User.find_by_username(params[:id])
end 

In routes.rb file:

  match '/:id' => 'profiles#show'
Sayanee
  • 4,957
  • 4
  • 29
  • 35
Egor
  • 120
  • 6
  • @Egor: Thanks! Yes, that would be helpful and I can use a gem or even devise. But i'm trying to learn and hence do from the basics without any gems. – Sayanee May 19 '11 at 09:35
  • 1
    You can override method to_param in our model to return username, and then search in your controller by username. I update the answer with details. – Egor May 19 '11 at 09:40
  • Thanks Egor! This however gives me http://localhost:3000/profile/username and not yet, http://localhost:3000/username. I guess, i'll need to amend the routes.rb as well? – Sayanee May 19 '11 at 09:50
  • You really want localhost:3000/username? It may be dangerous and confusing for your users. For example if someone take name like "articles", "posts", or "profile". If you still want localhost:3000/username you may need make some complicated routes or even hack Rails engine. – Egor May 19 '11 at 09:55
  • In routes you can write: match ":id" => "users#show". This make localhost:3000/username works fine. – Egor May 19 '11 at 10:04
  • Hi @Egor: Many thanks for your help! I did this in routes.rb: match '/:id' => 'profiles#show'. Now the url looks pretty like facebook/twitter or many other sites in the format of site.com/username :) – Sayanee May 19 '11 at 10:11
  • That's great. Worked for me as well. Just one thing... now other URLs like about, signup, contact and login don't work for me. –  May 21 '11 at 23:20
  • Moving the route for the username below the other pages fixes it, thanks! –  May 21 '11 at 23:21
1

This is what you need http://apidock.com/rails/ActiveRecord/Base/to_param

Pravin
  • 6,592
  • 4
  • 42
  • 51