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.
- Make the Admin Controllers
- Setup admin routes
- 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.
lang-ruby
#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
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!
lang-ruby
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.
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/
lang-erb
# 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 %>
<br>
<div>
<%= link_to "Show this make", [:admin, @make] %> |
<%= link_to "Back to makes", admin_makes_path %> |
<%= link_to 'add instruments', admin_make_pick_path(@make) %>
</div>
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.