ruby-on-railsrubyruby-on-rails-4seorails-routing

How to setup Rails routes.rb for Vanity URL without requiring a prefix


I'm looking to setup routes.rb to support vanity URLs that do not require a prefix. For example not requiring the "articles/" in mysite.com/articles/seo-url-here. I want just mysite.com/seo-url-here

How can I setup routes.rb so that when a url hits my site: routes.rb looks to see if the value of seo-url-here in the url matches a record in my database in the table Article.seo_url. If not match is found, then routes.rb should move on down through the rest of the routes.rb file.


Solution

  • Basic code to get you started:

    # config/routes.rb
    
    Rails.application.routes.draw do
      resources :posts
      resources :authors
    
      constraints(PostUrlConstrainer.new) do
        get "/:id", to: "posts#show"
      end
    end
    
    # app/constraints/post_url_constrainer.rb
    
    class PostUrlConstrainer
      def matches?(request)
        title = request.path_parameters[:id]
        Post.find_by(title: title)
      end
    end
    
    # app/controllers/posts_controller.rb
    
    def set_post
      @post = Post.find_by(title: params[:id])
    end
    

    Related article: Pretty, short urls for every route in your Rails app - Arkency Blog

    Searching for rails url constraint seems to help.