Routes with Dash `-` Instead of Underscore `_` in Ruby on Rails

Ruby on-RailsRoutingRails Routing

Ruby on-Rails Problem Overview


I want my urls to use dash - instead of underscore _ as word separators. For example controller/my-action instead of controller/my_action.

I'm surprised about two things:

  1. Google et al. continue to distinguish them.
  2. That Ruby on Rails doesn't have a simple, global configuration parameter to map - to _ in the routing. Or does it?

The best solution I've is to use :as or a named route.

My idea is to modify the Rails routing to check for that global config and change - to _ before dispatching to a controller action.

Is there a better way?

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

With Rails 3 and later you can do like this:

resources :user_bundles, :path => '/user-bundles'

Another option is to modify Rails, via an initializer. I don't recommend this though, since it may break in future versions (edit: doesn't work in Rails 5).

Using :path as shown above is better.

# Using private APIs is not recommended and may break in future Rails versions.
# https://github.com/rails/rails/blob/4-1-stable/actionpack/lib/action_dispatch/routing/mapper.rb#L1012
#
# config/initializers/adjust-route-paths.rb
module ActionDispatch
  module Routing
    class Mapper
      module Resources
        class Resource
          def path
            @path.dasherize
          end
        end
      end
    end
  end
end

Solution 2 - Ruby on-Rails

You can overload controller and action names to use dashes:

# config/routes.rb
resources :my_resources, path: 'my-resources' do
  collection do
    get 'my-method', to: :my_method
  end
end

You can test in console:

rails routes -g my_resources
my_method_my_resources GET  /my-resources/my-method(.:format) my_resources#my_method

Solution 3 - Ruby on-Rails

You can use named routes. It will allow using '-' as word seperators. In routes.rb,

map.name_of_route     'a-b-c',       :controller => 'my_controller', :action => "my_action"

Now urls like http://my_application/a-b-c would go to specified controller and action.

Also, for creating dynamic urls

map.name_of_route    'id1-:id2-:id3',       :controller => 'my_controller', :action => "my_action"

in this case 'id1, id2 & id2 would be passed as http params to the action

In you actions and views,

name_of_route_url(:id1=>val1, :id2=>val2, :id3=>val3) 

would evaluate to url 'http://my_application/val1-val2-val3'.

Solution 4 - Ruby on-Rails

if you use underscores in a controller and view file then just use dashes in your routes file, and it will work..

get 'blog/example-text' this is my route for this controller

def example_text end <-- this is my controller

and example_text.html.erb is the file

and this is the actual link site.com/blog/example-text

i figured this is works for me, and it's more effective than underscores SEO wise

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionpdueyView Question on Stackoverflow
Solution 1 - Ruby on-RailssandstromView Answer on Stackoverflow
Solution 2 - Ruby on-RailsLev LukomskyView Answer on Stackoverflow
Solution 3 - Ruby on-RailsKanView Answer on Stackoverflow
Solution 4 - Ruby on-RailsneinxView Answer on Stackoverflow