1

Ok guys, this might be a little bit confusing so stick with me. Let me start by introducing my tables. Basically I created four tables upon migration.

  • Students
  • Teachers
  • Subjects
  • Admin User

Here are my migration files:

Students:

def up
    create_table :students, :id => false do |t|
      t.integer "student_id",:primary_key => true
      t.string "first_name", :limit => 25
      t.string "last_name", :limit => 50
      t.string "email", :default => ' ', :null => false
      t.string "birthday"
      t.string "subjects"
      t.string "teachers"
      t.string "username", :limit => 25
      t.string "password_digest"
      t.timestamps
    end

Teachers:

def up
    create_table :teachers, :id => false do |t|
      t.integer "teacher_id", :primary_key => true
      t.string "first_name"
      t.string "last_name"
      t.string "email", :default => ' ', :null => false
      t.string "birthday"
      t.string "subjects"
      t.string "username", :limit => 25
      t.string "password_digest"
      t.timestamps
    end

Subjects:

def up
  create_table :subjects, :id => false do |t|
    t.integer "subject_id", :primary_key => true
    t.string "subject_name"
    t.timestamps
  end
end

Admin Users:

def up
  create_table :admin_users, :id => false do |t|
    t.integer "admin_user_id", :primary_key => true
    t.string "username", :limit => 25
    t.string "password_digest"
    t.timestamps
  end
end

So now let me get through the explanation. Basically:

  • one student can have many teachers
  • one teacher can have many students
  • one student can have many subjects
  • one teacher can teach many subjects
  • the admin can access all of this (create, edit, delete)

I created this fields and set them up on my models like this:

class Student < ApplicationRecord

  has_and_belongs_to_many :subjects
  has_and_belongs_to_many :teachers
  has_many :admin_users
  has_secure_password
  self.primary_key = :student_id

end

class Teacher < ApplicationRecord

  has_and_belongs_to_many :subjects
  has_and_belongs_to_many :students
  has_many :admin_users
  has_secure_password

end

class Subject < ApplicationRecord

  has_and_belongs_to_many :students
  has_and_belongs_to_many :teachers
  has_many :admin_users

  # scope :search, lambda { |query| where(["name LIKE ?", "%#{query}%"])}

end

class AdminUser < ApplicationRecord

  has_secure_password

  scope :newest_first, lambda { order("created_at ASC") }
  scope :oldest_first, lambda { order("created_at DESC") }
  # scope :search, lambda { |query| where(["name LIKE ?", "%#{query}%"])}
end

Now I manually inserted data on mysql data record and then tried to pull up the records for student's subjects and teachers form fields.

How can I manage my database effectively esp teachers, students, and subjects??? Is there anything I need to do first to correlate the tables I have? Please help. Sorry for the long post. I am a newbie here. Appreciate your explanation (layman's term) and answers.

Check my models. Do I need to create a separate table to correlate teachers, students, and subjects?

Side Note: When I pull up my students and teachers field it gives me an error ActiveRecord_Associations_CollectionProxy:0x007f9c504361d0 ERROR.

Pardeep Dhingra
  • 3,916
  • 7
  • 30
  • 56

1 Answers1

1

I think this relation should work in your case:

Students:

def up
  create_table :students, :id => false do |t|
    t.integer "student_id",:primary_key => true
    t.string "first_name", :limit => 25
    t.string "last_name", :limit => 50
    t.string "email", :default => ' ', :null => false
    t.string "birthday"
    t.string "subjects"
    t.string "username", :limit => 25
    t.string "password_digest"
    t.timestamps
  end
end

Ref: Generating auto increment with sequence 1001 Teachers:

def up
    create_table :teachers, :id => false do |t|
      t.integer "teacher_id", :primary_key => true
      t.string "first_name"
      t.string "last_name"
      t.string "email", :default => ' ', :null => false
      t.string "birthday"
      t.string "subjects"
      t.string "username", :limit => 25
      t.string "password_digest"
      t.timestamps
    end
end

Subjects:

def up
  create_table :subjects, :id => false do |t|
    t.integer "subject_id", :primary_key => true
    t.string "subject_name"
    t.timestamps
  end
end

Enrolled Subjects:

def up
  create_table :enrolled_subjects, :id => false do |t|
    t.integer "subject_id"
    t.integer "teacher_id"
    t.integer "student_id"
  end
end

Model:

class Student < ApplicationRecord
  has_many :enrolled_subjects
  has_many :subjects, through: :enrolled_subjects
  has_many :teachers, through: :enrolled_subjects    

  def teacher_names
    self.teachers.map(&:first_name).join(", ")
  end
end

class Teacher < ApplicationRecord    
  has_many :enrolled_subjects
  has_many :subjects, through: :enrolled_subjects
  has_many :students, through: :enrolled_subjects
end

class Subject < ApplicationRecord
  has_many :enrolled_subjects
  has_many :students, through: :enrolled_subjects
  has_many :teachers, through: :enrolled_subjects
end

class EnrolledSubject < ActiveRecord::Base
  belongs_to :student, foreign_key: :student_id
  belongs_to :subject, foreign_key: :subject_id
  belongs_to :teacher, foreign_key: :teacher_id
end

Example Repository

Community
  • 1
  • 1
Pardeep Dhingra
  • 3,916
  • 7
  • 30
  • 56
  • Can you explain more? can you also site Pardeep and edit my migration what fields is supposed to be there? Do I need to create a new table with studend_id, teachers_id, and subjects_id on that? –  Jan 27 '17 at 14:58
  • Also when I manually insert data from mysql will it automatically populate the teachers and subjects field when students enrolled? –  Jan 27 '17 at 14:59
  • Don't add data manually through mysql. Try rails console to add data instead. – Pardeep Dhingra Jan 27 '17 at 15:05
  • That shouldn't be a problem until you are adding relation data to in `EnrolledSubject`. I haven't tested this relation, please give it a shot and let me know if it works for you. I will add more explanation – Pardeep Dhingra Jan 27 '17 at 15:07
  • yeah on rails console. –  Jan 27 '17 at 15:07
  • last question. when I call this on my views. can it be like this? ***<%@students.each do |student|%> <%= student.student_id %> <%= student.username %> <%= student.first_name %> <%= student.last_name %> <%= student.email %> <%= student.birthday %> <%= student.teachers %> <%= student.subjects %> <% end %>*** –  Jan 27 '17 at 15:08
  • Didn't get you. Like what? – Pardeep Dhingra Jan 27 '17 at 15:10
  • Would that automaticall populate the data then? –  Jan 27 '17 at 15:12
  • `<%= student.teachers %>` and `<%= student.subjects %>` will be array of objects. You can't directly display it. you can create any helper method to help with that. like i am adding one in student model. – Pardeep Dhingra Jan 27 '17 at 15:12
  • Is there a way I can display the contents in a formatted text form for teachers and students? –  Jan 27 '17 at 15:13
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/134201/discussion-between-jim-carter-and-pardeep-dhingra). –  Jan 27 '17 at 15:14
  • now you can use `<%= student.teachers_name %>` this will return you comma separated teachers name. – Pardeep Dhingra Jan 27 '17 at 15:17
  • How about my admin user? am I going to just stick with my current migrations and models? (admin user is for the administrator) –  Jan 27 '17 at 15:18
  • We don't need to link `admin_users` with any table above. You can directly call All `students` and its related `subjects` and `teachers` as admin. – Pardeep Dhingra Jan 27 '17 at 15:20
  • I see. probably that would be on the access part. for now its good to know if it can pull it up. one moment. trying this out. –  Jan 27 '17 at 15:22
  • BTW Pardeep do you know a way to make the auto increment value for all of my id to start on a specific number upon migration lets say the student id must start on the number 1001 and then incrementing...DO you know? –  Jan 27 '17 at 15:24
  • I only used this *** t.integer "teacher_id", :auto_increment => true, :primary_key => true*** but i am not sure if we can put :default => 1001 –  Jan 27 '17 at 15:25
  • would that work on MYSQL? isnt that not for PostgreSQL? –  Jan 27 '17 at 15:42
  • I successfully migrated the files and tried to add a new record via rails console. **stud = Student.create(:student_id => 1, :first_name => 'Sam', :last_name => 'Norton', :email => 'samuelnico.norton@gmail.com', :birthday => '12/05/1990', :subjects => 'English', :username => 'samnorton05', :password => 'Grace0512')** BUT GOT THIS ERROR **ActiveRecord::HasManyThroughAssociationNotFoundError: Could not find the association :enrolled_subjects in model Student** –  Jan 27 '17 at 15:44
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/134307/discussion-between-pardeep-dhingra-and-jim-carter). – Pardeep Dhingra Jan 29 '17 at 15:59