TL;DR There are three dimensions you can control when scoping routes:
scope module: 'module', path: 'url_prefix', as: 'path_helper_name' do
resources :examples, only: :index
end
as
→ prefixes path helpers: path_helper_name_examples_path
and path_helper_name_examples_url
path
→ prefixes URL segments: /url_prefix/examples
module
→ nests the controller: controller Module::ExamplesController
, found at app/controllers/module/examples_controller.rb with views in app/views/module/examples/.
These options work with resources
as well, e.g. resources :examples, path: 'demonstration'
Two macros for namespacing routes
Rails offers two macros for namespacing routes. As its name suggests, namespace
is the tool for fully namespacing a group of routes. scope
on the other hand is fit for modifications of select properties for a group of route definitions. See the examples below.
-
scope
is a "plumbing method" that will only set the dimensions that you pass as arguments (module
,path
,as
). -
namespace
is a shorthand that sets its argument on all three dimensions. You can override dimensions by setting them as additionally.
Examples
Note that all of these examples could be implemented with either scope
or namespace
.
Changing URLs only
When you want to inject a "subdirectory" in URLs, but leave the corresponding controllers and url helpers unaffected, use the scope
method like this:
scope path: 'sub' do
resources :examples
end
- URL:
/sub/examples
- Route helper:
examples_path
- Controller class:
ExamplesController
A typical use case is the customer asking you to change some URLs.
Namespacing controllers and path helpers without changing URLs
When you want to namespace your controller classes (group some controllers into a folder) but leave the corresponding routes unaffected, use the namespace
method like this:
namespace 'module', path: '/' do
resources :examples
end
- URL:
/examples
- Route helper:
module_examples_path
- Controller class:
Module::ExamplesController
Namespacing without changing path helpers
When you want to namespace some resources of your application, but keep plain route helpers, use the scope
method like this:
scope module: 'module', path: 'module' do
resources :examples
end
- URL:
/module/examples
- Route helper:
examples_path
- Controller class:
Module::ExamplesController