Allow different roles and permissions (e.g. normal users vs. admins) in your app by separating actors with namespacing and actor specific controllers.

  1. Add an admin field in your users table which takes a boolean value.

     # schema.rb
    
       create_table "users", force: true do |t|
         t.string   "email"
         t.string   "password_digest"
         t.string   "full_name"
         t.datetime "created_at"
         t.datetime "updated_at"
         t.boolean  "admin"
       end
    
  2. Create a namespace in your routes
    • This allows us to specify how the actor “admin” can interact and have access to the resource “posts”. In this case see and delete “posts”.
    • For different actors we create different namespaces, i.e. adding another actor, such as a “superadmin” requires a new namespace.
    • You now have new routes, such as admin_posts_path linking to the controller action admin/posts#index. The corresponding URL will read domain.com/admin/posts.

     # routes.rb
    
     namespace :admin do
       resources :posts, only: [:index, :destroy]
     end
    
     namespace :superadmin do
       resources :users, only: [:index, :create, :destroy]
     end
    
  3. Create the actor specific admin controller

     # controllers/admin/posts_controller.rb
    
     class Admin::PostsController < ApplicationController
       def index
         @posts = Post.all
       end
    
       def destroy
       end
     end
    
  4. Nest your views under the same folder structure
    • views/admin/posts/index.html.erb
  5. Secure access by restricting admin urls to admin users

     before_action :ensure_admin
    
     def ensure_admin
       flash[:error] = "You do not have permission to access this area."
       redirect_to root_path unless current_user.admin?
     end
    

Structure your controllers with inheritance to account for different roles

# controllers/posts_controller.rb

class PostsController < AuthenticatedController
  # standard controller actions
  # ...
end
# controllers/authenticated_controller.rb

class AuthenticatedController < ApplicationController
  before_action :ensure_sign_in 
  # :ensure_sign_in is set as a helper method in the ApplicationController
end
# contollers/admins_controller.rb

class AdminsController < AuthenticatedController
  before_action :ensure_admin

  def ensure_admin
    flash[:error] = "You do not have permission to access this area."
    redirect_to root_path unless current_user.admin?
  end
end
# controllers/admin/posts_controller.rb

class Admin::PostsController < AdminsController
  def index
   @posts = Post.all
  end
end

A SuperAdminController would inherit from AdminsController, because a “SuperAdmin” also has to be “Admin”.

Keep in mind that your login doesn’t redirect to the normal views, but checks for admin status and redirects to the corresponding view.