ruby-on-rails-3routesnamed

replace user_id with username in show page in rails


Hell frens

I want to show a username instead of user_id in user's show page.

For example,

a usr_id 300 for a user named harry exist in database. So how to show

http://localhost:3000/harry

instead of

http://localhost:3000/user/300

in the url.

Can this be done within from the routes file?

Thanks


Solution

  • This is commonly referred to as a vanity URL, and with a little caution you can handle this quite easily. First...

    1. Make sure this is the last thing in your routes. You don't want your usernames overriding another controller's namespace.
    2. Use a sensible exclude list to prevent users from having usernames like admin, support, official, secure, etc.

    In your routes:

    # the simple case
    get '/:username' => 'users#show', :constrain => { :username => /[a-zA-Z-]+/ }
    
    # ...with vanity_url_path(@user) helpers
    get '/:username' => 'users#show', :as => 'vanity_url'
    
    # or routing something more complicated with all the default resourceful routes
    resources :users, :path => '/:username'
    
    # or even just defining a bunch of routes for users with this format
    controller :users, :path => '/:username' do
      get '/profile', :action => :profile    #=> /johnsmith/profile => UsersController#profile
    end
    

    In the above code, I avoided duplicating the :constrain option for each route for clarity. You will want to adjust the regular expression to match your usernames, and then make sure you do have it on whichever route you go with.

    If this is going to be the default way of accessing users from within your application (ie. not just a convenient way to access the profile of a user), you will want to override the to_param method on your Users model. This allows you to use the url_for helpers like form_for @user without specifying additional arguments.

    class User
      def to_param
        username
      end
    end
    

    Another quick tip: if you're playing with your routes and trying to do anything more than the basics, be sure to call $ rake routes often from the command line to see what routes Rails currently recognizes. Cleaning up ones you don't need is good to do, too. ;)