I am using Active Admin in my application.
The application has a Users model (Devise) but I have 3 user groups - parents, teachers and students. Each has their own model.
e.g
student.rb
belongs_to :user
user.rb
has_one :student
parent.rb
belongs_to :user
user.rb
has_one :parent
What I am trying to do here is store the attributes that would be the same across the user groups in the Users model so "first_name, last_name, email" etc and then using the individual user models to store attributes that are unique to each user group. I am using a one to one relationship between the main users table and the three user group tables.
Here (note I have not displayed all attributes in the user group tables):
The problem is this is not working out so well with Active Admin. In the view I have to create a user and then assign a parent and a student in different views. I would like to have a single form where, for example, a student's user record can be put in with the attributes from the main Users table as well as their unique attributes in the students table without having to go to multiple model views to complete records. It's too convoluted.
Is there a way to render the inputs from different models in the one view? i.e in students have "first name", "last name"...from the Users table along with the inputs unique to a student?
If you were taking the approach I am taking here what method would you follow? I'm not even sure I am doing the associations right. In fact i'm not even sure this is the most efficient way to do this.
I am using enums to assign the roles.
Would appreciate any guidance here. Thanks.
Student
s, Guardian
s, and Teacher
s are all a type of User. Why not consolidate them into a single type and use inheritance to represent them as a common type?
class User < ActiveRecord::Base
# ...
end
class Teacher < User
# ...
end
class Guardian < User
# ...
end
class Student < User
# ...
end
You'll need to add a type
column via a migration, and also write a task to merge them into a common table, but it will likely be worth the effort.
See STI in Rails: http://api.rubyonrails.org/classes/ActiveRecord/Inheritance.html.
EDIT:
If you don't want to go the STI route, you'll have to use nested attributes
class User < ActiveRecord::Base
accepts_nested_attributes_for :teacher
accepts_nested_attributes_for :guardian
accepts_nested_attributes_for :student
end
Then add a custom form
in admin/user.rb
():
ActiveAdmin.register User do
form do |f|
f.inputs "User Inputs" do
# ...
f.input :email
# ...
end
f.inputs "Guardian Attributes", for: [:guardian, f.object.guardian || Guardian.new] do |g|
g.input :mobile_no
end
# Repeat for teacher, Student, etc...
end
end
If you're using strong parameters, make sure you whitelist the appropriate params for User, guardian_attributes, etc.
In my opinion, the nesting here is pretty ugly and having this normalized schema is going to be difficult to maintain and query.