Using namespaces to organize your Rails code base
Sometimes you want to group areas of your application under one roof. For example, let's say you're building a multisided marketplace or building a CMS as part of your application. Let's pretend we're doing the latter.
Without namespacing, all of your resources would live in app/models
whether a part of the CMS or not. If we wanted to group the resources managed by the CMS portion of the application we could namespace them in a module.
Creating models under a namespace
The Rails generators support namespacing code using the namespace/resource
pattern.
bin/rails generate model cms/article title:string body:text
This generates a Cms
module at app/models/cms.rb
that defines the table prefix for the namespace:
module Cms
def self.table_name_prefix
'cms_'
end
The underlying table in PostgreSQL would be named cms_articles
, and the model in app/models/cms/article.rb
would look like the following:
module Cms
class Article < ApplicationRecord
end
end
Namespacing controllers and views
Let's say the resources for our CMS should be managed under the http://localhost:3000/cms
path in the URI. The Rails router makes this easy.
# frozen_string_literal: true
Rails.application.routes.draw do
namespace :cms do
resources :articles
end
end
and our controller would look something like this app/controllers/cms/articles.rb
:
module Cms
class ArticlesController < ApplicationController
def index
# code for /cms/articles here
end
end
end
and our corresponding views would live in app/views/cms/articles/index.html.erb
Conclusion
Namespacing our models has made a code base with several hundred models easier to navigate and reason about, and I think it is a pattern worth considering. Tomorrow we'll talk about setting up Rails to handle the acronyms in your codebase so that we can reference our CMS module as CMS
instead of Cms
.