Sebastian's dev time

Admin Gating in Ruby on Rails

The easiest way to protect your rails app
Say your rails app is looking awesome, but you need to protect the Create Update...(CRUD) functionality behind some authentication.  At the end of the tutorial, our app will have a realm that is view only, and another realm for editing and deleting stuff that begins with the /admin path. There are 3 steps to this. 

  1. Make the Admin Controllers 
  2. Setup admin routes 
  3. Admin in the Views 

Make the Admin Controllers

Begin by making a controller app/controllers/admin_controller.rb. This controller will use built in http_basic_authentication to require a password before anything occurs.
#app/controllers/admin_controller.rb. 
class AdminController < ApplicationController
   http_basic_authenticate_with name: 'username',    password: 'supersecret' 
end

Now create the admin module folder in controllers/.  Copy all the existing controllers except admin_controller.rb into this new folder.  Your controllers directory should now look something like this 
admin-controllers-directory-structure.png 97.9 KB

For all the copied controllers inside the controllers/admin folder, make them subclasses of AdminController instead of ApplicationController.  This will make sure we are authenticated before any of these controllers are called.
class Admin::CategoriesController < AdminController   
  before_action :set_category, only: %i[ show edit update destroy ] 
... 
end
For the controllers outside of admin, remove the update, create, destroy and new methods so that your controllers have only index and show.  No way to edit or tamper with any content now with those controllers!
class CategoriesController < ApplicationController   
  before_action :set_category, only: :show   
  # GET /categories or /categories.json   
  def index     
    @categories = Category.all
   end   
   # GET /categories/1 or /categories/1.json
   def show
   end
   private
       ...
end

Setup Admin Routes

We'll use the route helper namespace for all the admin resources for CRUD.  Simply copy paste your resources into the namespace block.  Then with the resources outside the namespace block, make sure to specify they only have show and index actions for those controllers with  ", only: [:index, :show]"

#application/config/routes.rb
Rails.application.routes.draw do
  ...  
  namespace 'admin' do
   ...
    get 'categories' => 'categories#index', as: 'categories'
    post 'categories' => 'categories#create'
    post 'categories' => 'categories#create'
    resources :categories, except: [:index, :create], param: :slug, path: '/' do
      resources :makes, param: :slug
   end
  end # scope admin
  # visitor only
  resources   resources :categories, only: [:index, :show], param: :slug, path: '/' do
      resources :makes, only: [:index, :show], param: :slug
  end ... end

Admin in the Views


If you ran into a bunch of errors after changing the Routes.rb file that is to be expected.  So many views in the app use those CRUD routes, that are now somewhere else.  Let's fix this. Start by copying your scaffold view folders into a new folder app/views/admin.  Now your directory should look something like this.

after-moving-updating-admin-directory.png 69.3 KB

Next we have to go through all the non-admin views and remove all admin specific parameters.  Remove the edit pages, and all edit, new, and destroy buttons in non-admin views.

Then, in the admin views, add the :admin symbol before your @variables
[:admin, @make] # for show

# in a form helper
<%= form_with model: [:admin, category] do |form| %> 
This tells rails that /admin_ route is needed such that these paths connect correctly  to the admin controller not the regular show-only controllers.
Also add admin_ in front of all of your admin-only paths.  Below is an example for the edit.html.erb under views/admin/makes/
# for form helpers we have to specify the :admin param 
# so it knows what namespace to generate the path for 

<h1>Editing make<h1> 

<%= render "form", make: @make %> 

<%= link_to "Show this make", [:admin, @make] %> |
<%= link_to "Back to makes", admin_makes_path %> | 
<%= link_to 'add instruments', admin_make_pick_path(@make) %> 


Conclusion

In this tutorial we went over how to refactor your rails application to use a protected admin module.  We edited the views and controllers to make this all work as expected. There was a lot of work behind this, so please have a look at the resources below for more on how to admin gate your ruby on rails app. 

Sources:

github repository saxshop
The commit where you can see most of this work
Stack overflow:
  1. rails-routes-namespaces-and-form-for
  2. rails-using-link-to-with-namespaced-routes
Rails:
  1. Obie Fernandez rails-7-way
  2. https://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Basic.html
  3. https://guides.rubyonrails.org/routing.html#controller-namespaces-and-routing
Previous Article: slugifying the saxshop app
updated: 2025-08-03 22:49:55 UTC