Right now my user profile URLs are like so:
http://example.com/users/joeschmoe
And that points to the show
method in the user controller.
What I'd ideally like to do is offer user profile URLs like this:
http://example.com/joeschmoe
So, what sort of route and controller magic needs to happen to pull that off?
I disagree with what jcm says about this. It's not a terrible idea at all and is used in production by the two biggest social networks Facebook and MySpace.
The route to match http://example.com/username
would look like this:
map.connect ':username', :controller => 'users', :action => 'show'
If you want to go the subdomain route and map profiles to a URL like http://username.example.com/
, I recommend using the SubdomainFu plugin and the resulting route would look like:
map.root :controller => 'users', :action => 'show' , :conditions => {:subdomain => /.+/}
These broad, catch all routes should be defined last in routes.rb, so that they are of lowest priority, and more specific routes will match first.
I also recommend using a validation in your User model to eliminate the possibility of a user choosing a username that will collide with current and future routes:
class User < ActiveRecord::Base
validates_exclusion_of :username, :in => %w( messages posts blog forum admin profile )
…
end
This does not make sense unless you have no controllers. What happens when you want to name a controller the same as an existing user? What if a user creates a username the same as one of your controllers? This looks like a terrible idea. If you think the /user/ is too long try making a new custom route for /u/
So your custom route would be...
map.connect 'u/:id', :controller => 'my/usercontroller', :action => 'someaction'
In routes.rb this should do the trick:
map.connect ":login", :controller => 'users', :action => 'show'
Where login is the name of the variable passed to the show method. Be sure to put it after all other controller mappings.
Well, one thing you need is to ensure that you don't have name collisions with your users and controllers.
Once you do that you, can add a route like this:
map.connect ':username', :controller => 'users', :action => 'show'
Another thing people have done is to use subdomains and rewrite rules in the web server, so you can have http://joeshmoe.example.com
In Rails 4 to skip controller from url you have to do add path: ''
.
resources :users, path: '' do
end