user258980
user258980

Reputation: 663

How can I implement vanity URL's in a Rails application?

I want users to able to have a profile page at site.com/myNameHere. Rails looks for a controller named "myNameHere." Is it possible to setup routes.rb so that if the controller is not found, "myNameHere" gets sent as a parameter to another controller?

Upvotes: 9

Views: 3986

Answers (2)

Jaime Bellmyer
Jaime Bellmyer

Reputation: 23307

You can add a route like this:

map.profile_link '/:username', :controller => 'profiles', :action => 'show'

Be sure to add it low enough in the file, below your resources, that it doesn't interfere with other routes. It should be lowest priority. Next, you need to change your show action to use a username instead of id:

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

That's all there is to it. Happy coding!

UPDATE:

I've expanded this answer into a full blog post, Vanity URLs in Ruby on Rails Routes. I have additional code samples and a more thorough explanation.

Upvotes: 9

Mark Locklear
Mark Locklear

Reputation: 5325

Just thought I would update this for Rails 3. I have a field 'website' in my user model that is going to act as the vanity route, and I am going to route to a static page for each vanity route. I want to display all of a users 'events' if the vanity route is called.

#config/routes.rb
  get '/:website', :controller => 'static_pages', :action => 'vanity'

#app/controllers/static_pages_controller.rb
  def vanity
      @user = User.find_by_website(params[:website])
    if @user != nil #in case someone puts in a bogus url I redirect to root
      @events = @user.events
    else
      redirect_to :root
    end
  end

#app/views/static_pages/vanity.html.erb
<h1><%= @user.website  %> events</h1>

<table>
  <tr>
    <th>Title</th>
    <th>Starts at</th>
    <th>Description</th>
    <th></th>
    <th></th>
    <th></th>
  </tr>

<% @events.each do |event| %>
  <tr>
    <td><%= event.title %></td>
    <td><%= event.starts_at %></td>
    <td><%= event.description %></td>
  </tr>
<% end %>
</table>

I think this is a good alternative if you don't want to use a gem.

Upvotes: 0

Related Questions