Search code examples
ruby-on-railsurlurl-routingfriendly-id

URLs are UI in Rails 5


Came across this blog post recently and wanted to Incorporate its ideas into my Rails project - URLs should be short, human readable, shareable, and shorten-able. Specifically, I want to learn how to make URLs shorten-able with Rails. The example he gives is https://stackoverflow.com/users/6380/scott-hanselman and https://stackoverflow.com/users/6380 are the same URLs, the text after the ID is ignored and scott-hanselman will be added after navigating to the page. This improves readability and share-ability.

I would like the show action in my resource URLs to auto-add the page's <title> after the ID when navigating to the page but ignore it when the user pastes it into the search bar. This allows for malleable titles.

Example below. All these URLs should bring you to the resource with an ID of '1'

host/resource/1/exciting-blog-post

host/resource/1

host/resource/1/exciting-blog-post.html

host/resource/1/new-title-on-post

Edit:

The biggest difficulty I am having is editing the URL after the user submits it, ie transforming resource/1 to resource/1/name_column.

I have been able to redirect incorrect routes using the following in config/routes.rb - get "/events/:id/*other", to: redirect('events/%{id}')


Solution

  • Ok this was really tricky to figure out, didn't even know I had access to a lot of these parameters before. FriendlyID is not required, and not even capable of solving this issue.

    The resource I'm using below is "events".

    First edit your config/routes.rb to accept id/other_stuff

    Rails.application.routes.draw do
      resources :events
      get "/events/:id/*other" => "events#show" #if any txt is trailing id, also send this route to events#show
    end
    

    Next modify event_controller.show to redirect if the URL is incorrect.

      def show
        #redirect if :name is not seen in the URL
        if request.format.html? 
          name_param = @event.name.parameterize
          url = request.original_url
          id_end_indx = url.index(@event.id.to_s) + (@event.id.to_s).length + 1 #+1 for '/' character
          ##all URL txt after id does not match name.parameterize
          if url[id_end_indx..-1] != @event.name.parameterize
            redirect_to "/events/#{@event.id}/#{name_param}"
          end
        end
      end
    

    This will result in the exact same behavior as the Stack Overflow examples gave in the question.