There isn’t a single right answer to this, and the best approach will likely depend on your particular application. Your approach is definitely viable, but you might want to go with something a little different depending on your needs.
Consider some of these questions:
-
Do you expect that school accounts will have various roles (like teacher, administrator, etc.?). If so, there might be a relationship you want to have that applies to school accounts, but not parent accounts.
-
Do you expect someone to be able to have both a parent account and a school account (i.e. a teacher that is also a parent?) If so, your authorization library will need to be smart enough to distinguish accounts based on something more than the email address (or, you’ll have to use separate tables for each kind of account.)
-
Do you expect additional attributes for school accounts vs. parent accounts? For example, perhaps a school account needs a title (like Principal or Teacher or Coach), whereas a parent would have no such title.
At the very least, I would introduce one more model called SchoolUser
to separate Account
from School
like this:
class Account < ActiveRecord::Base
belongs_to :user, polymorphic: true # Either a `Parent` or a `SchoolUser`
end
class SchoolUser < ActiveRecord::Base
has_one :account, as: :user
# Has attributes that a parent doesn't have like `title`, `employment_year`, etc.
# Also might have associations that a parent doesn't have:
has_many :school_user_roles, through: :school_user_role_assignments
end
class School < ActiveRecord::Base
has_many :school_users
end
class Parent < ActiveRecord::Base
has_one :account, as: :user
end
For my applications I generally go a little further and put different “kinds” of users in completely separate tables. This allows various relationships to be more explicit (i.e. no STI and no polymorphic relationships):
class SchoolUser < ActiveRecord::Base
# this model can login
belongs_to :school
has_many :school_user_roles, through: :school_user_role_assignments
end
class Parent < ActiveRecord::Base
# this model can login too
end
There are definitely appropriate situations for STI and polymorphic associations, but you sacrifice a little bit of clarity when you use them.
One downside to using separate authentication tables for different kinds of users is that your application might end up with more redundancy, if you’re not careful.
At the end of the day, try an approach and see how it works for you. You can always change it later.