How to Use Scope in Routes in Ruby on Rails
In Ruby on Rails, use
scope in routes to group related paths under a common URL prefix or options without changing the controller namespace. It helps organize routes by adding path prefixes or constraints while keeping controller references simple. Use scope with a path or other options inside the routes.rb file.Syntax
The scope method wraps routes to apply common options like URL prefixes or constraints without altering controller namespaces. You can specify path to add a URL prefix or module to change controller namespaces.
- scope :path => 'prefix': Adds a URL prefix to all nested routes.
- scope :module => 'admin': Changes controller namespace for nested routes.
- scope :constraints => {subdomain: 'api'}: Adds constraints like subdomain.
ruby
Rails.application.routes.draw do scope path: 'admin' do get 'dashboard', to: 'dashboard#index' end scope module: 'admin' do resources :users end end
Example
This example shows how to use scope to add a URL prefix /admin to a route and how to use scope with module to route to controllers inside an Admin namespace.
ruby
Rails.application.routes.draw do # Adds /admin prefix to URL but controller stays the same scope path: 'admin' do get 'dashboard', to: 'dashboard#index' end # Routes to Admin::UsersController without changing URL scope module: 'admin' do resources :users end end
Output
GET /admin/dashboard routes to DashboardController#index
GET /users routes to Admin::UsersController#index
POST /users routes to Admin::UsersController#create
Common Pitfalls
Common mistakes when using scope include confusing scope with namespace, which changes controller namespaces and URL prefixes automatically. Another pitfall is forgetting that scope with path only changes the URL path, not the controller module, so controller references must be explicit.
Also, nesting scope incorrectly can lead to unexpected URL structures or routing errors.
ruby
Rails.application.routes.draw do
# Wrong: expects Admin::DashboardController but controller is DashboardController
namespace :admin do
scope path: 'dashboard' do
get '/', to: 'dashboard#index'
end
end
# Right: use scope with path without namespace
scope path: 'admin' do
get 'dashboard', to: 'dashboard#index'
end
endQuick Reference
| Option | Effect |
|---|---|
| path: 'prefix' | Adds URL prefix to nested routes |
| module: 'name' | Changes controller namespace for nested routes |
| constraints: {key: value} | Applies constraints like subdomain or format |
| as: 'name' | Prefixes route helper names |
Key Takeaways
Use
scope to group routes with a common URL prefix without changing controller namespaces.Use
scope module: to route to controllers inside a specific namespace without changing URL paths.Do not confuse
scope with namespace; namespace changes both URL and controller module.Remember
scope path: only affects URL paths, so specify controllers explicitly if needed.Avoid nesting
scope incorrectly to prevent unexpected route behavior.