Dave Woodall

Moving files under a namespace in Rails

Last Updated: August 6, 2021

I’m working on a Rails App that was initially designed as an internal tool. The company began receiving customer requests for reports the application produced. The decision was made to create a User Interface (UI). The process included adding creating user roles, adding authorization (with Pundit), and moving files into namespaces. There were about 10 endpoints that needed to be moved. After moving a few endpoints I detected a pattern that converted into a checklist.

The first step was to verify or add a simple test to confirm 200 before making any changes. Here is an example:

  describe 'GET Index' do
    it '200' do
      get reports_path
      expect(response).to have_http_status(200)
    end
  end

There was a corresponding spec for the relevant resources (index, show, new, edit, delete)

The next step was to move the resource under the namespace like so:

Before:

  # routes.rb
  resources :reports

After:

namespace :admin do
  resources :reports
end

Running the test highlighted each of the files that needed updating. The list included:

Controllers

Controllers must be moved and wrapped in a module.

Before:

The directory structure:

/app
 /controllers
  /files_controller.rb

The controller without a namespace:

class FilesController < ApplicationController
end

After:

The directory structure:

/app
 /controllers
  /admin
   /files_controller.rb

The controller with a namespace:

module Admin
  class FilesController < ApplicationController
  end
end

Views

The directory structure:

Before:

/app
 /views
  /reports

After:

/app
 /views
  /admin
   /reports

Pathname helpers

Namespacing routes changes the path helpers. It is helpful to review rake routes | grep [resource_name] to see how they change.

Partials

Partials also must be updated. For example if reports were to be namespaced under admin a partial path would start like so: <%= render 'reports', %> then need to add admin to the path:
<%= render 'admin/reports', %>

Forms

Rails forms have a few different syntaxes. The one used follows this pattern:

form_with(model: [:report, @report]

Once there was a namespace (such as admin) then the namespace (:admin) became the initial argument in the form like so:

form_with(model: [:admin, :report, @report]