The pattern I've used before is to have a base User class (essentially
what
restful_authentication generates), and then derive the various types
of users from
that class. You'll need to add a string column named 'type' to your
users table for this
to work.
So your Teacher class would be declared as:
class Teacher < User
# teacher specific stuff
end
This works great for cases where users are cleanly divided into roles
(ie, Teachers are never Students). It also makes it easy to add access
control: define methods to check access on the user models, and then
call them in the views.
Example (viewing grades):
# user.rb
class User < ActiveRecord::Base
def can_view_grades?(student)
false
end
end
# student.rb
class Student < User
def can_view_grades?(student)
# more if needed here...
self == student
end
end
# teacher.rb
class Teacher < User
def can_view_grades?(student)
true
end
end
That makes the check in GradesController very short:
class GradesController < ApplicationController
def index
# assumes that grades are a nested resource under student
@student = Student.find(params[:student_id]
return access_denied unless current_user.can_view_grades?
(@student)
# etc
end
end
This also makes it easy to add, say, an Admin user type that can view
*everybody's* grades. Just create another subclass!
It also allows different types of users to have different associations
- for example:
class Teacher < User
has_many :student_class_assignments
has_many :students, :through => :student_class_assignments
end
class StudentClassAssignment < ActiveRecord::Base
belongs_to :teacher
belongs_to :student
# adding another association here to indicate which section/class
this is is left to the reader
end
class Student < User
has_many :student_class_assignments
has_many :teachers, :through => :student_class_assignments
end
It's also handy to have methods to check the type of a user; in this
case, "teacher?" and "student?".
Finally, on the navigation issue, it's relatively straightforward to
check the type of current_user and pick what to display. In several of
my apps, there's an individualized nav partial per user type, but your
case may be different.
Hope this helps!
--Matt Jones