3

I am using Devise and Rails 4. I want to add multiple User Models(admin, usertype1, usertype2) such that they inherit from the main User Model. I have searched many posts and come to the conclusion that I may use CanCan, which I do not want, or I may use Single Table Inheritance.

The way I see it is to add a type string-column to my main User model I created with Devise. I will also need to extend each sub-class from the parent as in:

class Admin < User
end

class Usertype1 < User
end

class Usertype2 < User
end

My question is: what do I do next? How exactly do I know how to access the type column? Do I also need to override the Devise Controller for the current_user helper method such that I can have current_admin for example?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Claudiu S
  • 1,587
  • 6
  • 22
  • 40

3 Answers3

3

I'm not sure this really answers the original question. I am trying to set up multiple session controllers for Devise, and it seems like it really does require multiple models for this use case. Will post back when I've got a working version.

Jason Newell
  • 591
  • 6
  • 11
1

You can also use the easy_roles gem. It is available on github. This gem provides a bitmask solution for your different user roles. You just must have one model, e.g User, this model gets an attribute "role". Just checkout the docs on github. Devise + easy_roles + CanCan is a very good setup, it is very convenient in my opinion. I use this quite often.

Link to github: https://github.com/platform45/easy_roles

Matthias
  • 4,355
  • 2
  • 25
  • 34
  • Thanks mate! I've successfully added both into my project and they both work. Now, I do understand that easy_roles adds a new column to your user model. What I don't understand is where does it actually create the subclasses? Does it do that? – Claudiu S Aug 06 '13 at 02:31
  • 1
    What do you mean? The STI subclassss? You won't need them anymore. You just can define different methods to get the different user roles. For example you define a def has_role?(role) or something similar and you get back the different roles. You also can add multiple roles to one user through the provided bitmask solution. – Matthias Aug 06 '13 at 06:51
  • What about the data for those sub-classes? Where does it get stored or potentially how would I be able to add particular columns to each sub class? Thanks again – Claudiu S Aug 06 '13 at 10:32
  • 1
    You don't have any sub-classes :). Everything is stored within your users_table. You have users with different roles, but the class behind an instance of an user with the role "admin" is also User. "admin", "user", "editor", "foo", "bar" => roles.. class => User. So this gem does not provide STI for you. It is an alternative to avoid STI. – Matthias Aug 06 '13 at 11:08
  • Will this not cause any database design issues as in, when you get to many entries in the database, it will become slow? Thanks for taking your time. Really appreciate it :) – Claudiu S Aug 06 '13 at 20:00
  • 1
    That depends on the database type you´re using..mysql, sqlite3, postgresql, ... But if you are setting your indexes correctly, you can deal with a lot of users. You easily can define different scopes, for querying different users with specific roles..such stuff is up to you. It depends on your needs :). I never had performance problems, because of this user-authentication setup ;). – Matthias Aug 06 '13 at 23:27
0

STI will give you current_admin, current_user1 and current_user2 Devise methods.

In application_controller.rb, create a custom current_user method like this:

  def current_user
    if current_admin
      current_admin
    elsif current_user1
      current_user1
    else
      current_user2
    end
  end
helper_method :current_user

You will need some work on routes.rb and a custom sessions_controller.rb. See the accepted answer here Rails: Using Devise with single table inheritance

Community
  • 1
  • 1
Yimanei
  • 242
  • 2
  • 8