Reputation: 2303
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
Polymorphic Relationship. User model, with Admin, Manager and Client inheriting. The question here is how can I restrict each model to their respective controller?
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
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