Namespace vs Scope in Rails Router
Difference and Similarity in the use cases between Namespace and Scope in Rails Router
When it comes to customization to Rails routes, some options like namespace and scope pops up which also has a lot of use case and importance in Rails application. It’s very common to forget about the difference between the two terms ‘namespace
’ and ‘scope
’, so let’s look into the working for each of the terms in this section.
Namespace
Starting with the simple topic among the two as :namespace
. So basically :namespace
changes (prefix name with) URL along with controller directory structure.
config/routes.rbRails.application.routes.draw do
namespace :api, defaults: { format: :json } do
resources :homes
end
end
Then the routes available will be given as,
terminal=>$ rake routes | grep homesPrefix Verb URI Pattern Controller#Actionapi_homes GET /api/homes(.:format) api/homes#index {:format=>:json}
POST /api/homes(.:format) api/homes#create {:format=>:json}
api_home GET /api/homes/:id(.:format) api/homes#show {:format=>:json}
PATCH /api/homes/:id(.:format) api/homes#update {:format=>:json}
PUT /api/homes/:id(.:format) api/homes#update {:format=>:json}
DELETE /api/homes/:id(.:format) api/homes#destroy {:format=>:json}
So the Prefix name got a prepend ‘api’, URL has a prepend /api
and even the controller structure needs to get modified as,
app/controllers/api/homes_controller.rbmodule Api
class HomesController < ApplicationController # GET /api/homes
def index
end end
end
Scope
Similar to the :namespace, the :scope
has few options which can control the changes in URL path, controller structure and Prefix path. Scope provides few options of :path
, :as
and :module
. Generally the scope can be given as follows,
config/routes.rbRails.application.routes.draw do
scope :api do
resources :homes
end
end
This will make available routes to change only the URL path (URI pattern) with prepend ‘/api
’ as below,
terminal=>$ rake routes | grep homesPrefix Verb URI Pattern Controller#Actionhomes GET /api/homes(.:format) homes#index
POST /api/homes(.:format) homes#create
home GET /api/homes/:id(.:format) homes#show
PATCH /api/homes/:id(.:format) homes#update
PUT /api/homes/:id(.:format) homes#update
DELETE /api/homes/:id(.:format) homes#destroy
Scope with :module
The scope with the :module
will change only the controller structure as below,
config/routes.rbRails.application.routes.draw do
scope module: ‘api’ do
resources :homes
end
end
The available routes will be as follows,
terminal=>$ rake routes | grep homesPrefix Verb URI Pattern Controller#Actionhomes GET /homes(.:format) api/homes#index
POST /homes(.:format) api/homes#create
home GET /homes/:id(.:format) api/homes#show
PATCH /homes/:id(.:format) api/homes#update
PUT /homes/:id(.:format) api/homes#update
DELETE /homes/:id(.:format) api/homes#destroy
Scope with :path
The scope with the :path
will change only the URL path (URI Pattern) as below,
config/routes.rbRails.application.routes.draw do
scope module: ‘api’, path: ‘api’ do
resources :homes
end
end
The available routes will be as follows,
terminal=>$ rake routes | grep homesCPrefix Verb URI Pattern Controller#Actionhomes GET /api/homes(.:format) api/homes#index
POST /api/homes(.:format) api/homes#create
home GET /api/homes/:id(.:format) api/homes#show
PATCH /api/homes/:id(.:format) api/homes#update
PUT /api/homes/:id(.:format) api/homes#update
DELETE /api/homes/:id(.:format) api/homes#destroy
Scope with :as
The scope with the :as
will change only the Prefix as below,
config/routes.rbRails.application.routes.draw do
scope module: ‘api’, path: ‘api’, as: ‘api’ do
resources :homes
end
end
The available routes will be as follows,
terminal=>$ rake routes | grep homesPrefix Verb URI Pattern Controller#Actionapi_homes GET /api/homes(.:format) api/homes#index
POST /api/homes(.:format) api/homes#create
api_home GET /api/homes/:id(.:format) api/homes#show
PATCH /api/homes/:id(.:format) api/homes#update
PUT /api/homes/:id(.:format) api/homes#update
DELETE /api/homes/:id(.:format) api/homes#destroy
As shown in this last example, well it’s similar to namespace as it uses all the options available to scope, the change is just that prepend name in different options can have different values in scope.