How can I implement vanity URL's in a Rails ap

2019-01-17 13:03发布

问题:

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?

回答1:

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.



回答2:

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.