Anthony To
Anthony To

Reputation: 2303

How can I properly set up Rails 4 Devise authentication with three different user types and different authorizations for each type?

So I've been chewing on this problem for a few days now and couldn't come up with an eloquent solution. There are a few resources online but they are not very comprehensive. Here is my situation:

Specs

Currently, I have Devise set up with a User class, and a polymorphic relationship between User and Admin, Manager, Client. I tried using a single table inheritance, but due to the fact that each user type has varying attributes I wanted to avoid a large single table with many null values.

Proposed solutions

  1. Polymorphic Relationship. User model, with Admin, Manager and Client inheriting. The question here is how can I restrict each model to their respective controller?

  2. User model, with a has_one relationship with a ClientProfile and ManagerProfile to handle the extra attributes. Then use declarative_authorization or CanCanCan to restrict authorizations. This helps keep the app DRY by keeping only one User model, but view logic then gets complicated.

Of the two solutions, which one seems more scalable, clean and secure? If there are any other suggestions for general app architecture that would be better? Thanks!

Upvotes: 1

Views: 252

Answers (1)

MZaragoza
MZaragoza

Reputation: 10111

This is how I have my app set up form multiple user types on ROR

#config/routes.rb
AppName::Application.routes.draw do
    devise_for :users, :controllers => {
    registrations: 'users/registrations',
    :sessions => "users/sessions",
    :passwords => 'users/passwords',
    :confirmations => 'users/confirmations'
  }

  authenticate :user do
    namespace :users do
      ....
      get '/' => 'dashboards#index'
      root :to => 'dashboards#index'
    end
  end

  devise_for :admins, :controllers => {
    :sessions => "admins/sessions",
    :passwords => 'admins/passwords',
    :confirmations => 'admins/confirmations'
  }

  authenticate :admin do
    namespace :admins do
      ....
      get '/dashboard' => 'dashboards#index
      root :to => 'dashboards#index'
    end
  end
  root 'pages#index'
end

Now that you have your routes in place you can create your controllers

I have

#app/controllers/user_controller.rb
class UserController < ApplicationController
  before_filter :authenticate_user!
  layout 'users/default'
  before_filter :check_user_active

  private
  def check_user_active
    unless current_user.active
      flash[:notice]= t(:user_not_active)
      sign_out current_user
      redirect_to new_user_session_path
    end
  end
end



# app/controllers/users/sessions_controller.rb
class Users::SessionsController < Devise::SessionsController
  layout 'users/login'

   def create

  end

  def destroy
  end
end

Last but not least is the views

just put everything in its name space like #app/views/users/sessions/new.html.haml

Upvotes: 0

Related Questions