Short explanation:
I seek architectural advice and help in implementing multiple Devise models in a single app.
More detailed explanation:
My application needs to perform the following behavior:
There are 3 types of users (Partner
, Attendee
, Speaker
) which have some common fields and some unique ones (also, the fields might have different permissions, i.e. Attendee
must have a username whereas the Speaker
might have it but they don't have to necessarily fill this field in). And moreover, the different user models must have different associations with other tables in the db.
The users need to be able to log in through single log-in form, but the sign-up forms should be different.
So, my first thought was that I should divide the users by roles using Pundit
or declarative_authorization
or something, but the users don't really have different roles (i.e. permissions) in the app, they rather have different behavior, they might see different content and stuff, so I continued thinking.
My second though was implementing STI and after reading several articles about it, I tried to do that in code.
I generated a Devise User
model by doing rails g devise User
and after that ran rails g model Attendee
and the same for other two users.
Then, I inherited my models from User
:
class Attendee < User
end
My User
migration looks like this:
create_table :users do |t|
t.string :first_name
t.string :last_name
t.string :type
# Devise stuff ...
..................
t.timestamps null: false
end
And other migrations are like this:
create_table :attendees do |t|
t.string :username
t.string :company_name
t.boolean :subscription
t.timestamps null: false
end
Now I realize it was wrong to create separate tables.
I had to put all the possible fields into the User
table, is that correct?
Because now when I try to create any new Attendee
or Speaker
or Partner
in rails console
, all of these three models have the exact same fields, those the User
model has.
But if I add all the possible fields in the User
model, how would I perform validations on field presence?
I've read quite a few articles and questions here on SO, but still can't really wrap my head around how to implement all that.
Anyway, is that a correct way to do what I need?
Could anybody explain me in a detailed way how I should implement this kind of behavior and functionality from start to finish, and how should I work with the models after having implemented them?
PS: here's the history of my migrations and the whole github repo
Update
Remembered another issue that stopped my from doing just role separation:
How should I sign up the different users with different sign-up forms? Different routes? I cannot make the user choose their role from the combobox.