Namespacing controllers in a Ruby on Rails application is a great way to isolate different features: invoicing, authentication, etc. It’s also pretty simple to implement, so there are no reasons not to do it if you need it.
The initial state
Let’s start with a sample controller named ProposalsController
:
# app/controllers/proposals_controller.rb
class ProposalsController < ApplicationController
def index
# something cool is probably happening here
end
end
This file currently lives in app/controllers/proposals_controller.rb
, and the routes are:
# routes.rb
resources :proposals, only: [:index]
Moving things up
Now let’s say we want to move this controller into a module named Invoice
. Here are the steps to follow to add a namespace.
1. Create the folder app/controllers/invoice
The first thing to do is create a new folder under app/controllers
, named invoice
.
2. Move the proposals_controller.rb
file in the invoice
folder
3. Add the namespace to the ProposalsController
This is done with the module
keyword from Ruby that will encapsulate the ProposalsController
class.
# app/controllers/invoice/proposals_controller.rb
module Invoice
class ProposalsController < ApplicationController
def index
# something cool is probably happening here
end
end
end
4. Add a scope or a namespace in the routes
For the change to routes.rb
, we have two options, depending on how we want the URI path to be affected.
With this first solution, the generated path in the browser will be /invoice/proposals
, and it will use the controller located at app/controllers/invoice/proposals_controller.rb
.
# routes.rb
namespace :invoice do
resources :proposals, only: [:index]
end
This second solution will not add anything to the path. The proposals will be available at /proposals
, and use the controller located at app/controllers/invoice/proposals_controller.rb
.
# routes.rb
scope module: :invoice do
resources :proposals, only: [:index]
end
The End
That’s it, let me know if you have any comments!