I understand now. On my first attempt, I would try keeping Students and Admins in separate tables. Then when someone tries to login, attempt to match them to the Students table. If there are no matches, attempt to match them in the Admins table.
This is a very wet solution, but it would allow you to match many admins with many schools, but only keep one school per student. Maybe someone can come up with a more dry solution that doesn’t make this harder to maintain.
instead of roles you can use STI (single table inheritance) where you
have one table and one model, but then the model gets extended with
other classes:
class User < AR::Base
has_many :memberships
end
class Student < User
has_one :school, :through => :memberships
end
class Admin < user
has_many :schools, :through => :memberships
end
Now, Admin and Student are both Users, but Student has the methods
schools, school= ...etc, whistl admins have schools, schools<<... etc.
Your table users will need a column called type which is a string and
you will never actually use it explicitely, so just put it there and
forget about it.
obviously:
Student.all #=> an array of only students
Admin.all #=> an array of only admins
User.all #=> an array of all users: User + Students + Admins
This is a very common scenario that comes up all the time. The problem
is that there isn't a "silver bullet" solution for this. Different
applications often end up with different needs.
Here are some of the solutions I've used in the past for various
applications:
1. Single-table Inheritance (STI)
This can be a robust solution that covers a large number of
applications. In this solution login could be handled by a User class
(probably abstract), with subclasses for Student and Admin. Data for all
types of users are stored in a single database table with a qualifying
column (usually a type column) which designates the subclass of the User
instance. Find more by searching for Single-table Inheritance, or STI.
2. Polymorphic association
This can be used to provide additional flexibility beyond that provided
by STI. Google this for more information.
3. Access Control Lists (ACL)
This is the "industrial strength" solution. It is extremely flexible,
also making it complex relative to 1 & 2 above.
This is a very common scenario that comes up all the time. The problem
is that there isn't a "silver bullet" solution for this. Different
applications often end up with different needs.