NicSlim
NicSlim

Reputation: 339

Rails - should i use a polymorphic association?

I have a Student and a Teacher model in my app. I want a teacher to be able to create a Task that the Student can complete multiple times, but I also want the Student to be able to create his/her own Task. This is my current model structure:

class Task < ActiveRecord::Base
 belongs_to :teacher
 belongs_to :student
 has_many :completed_tasks

class Student < ActiveRecord::Base
 belongs_to :teacher
 has_many :tasks
 has_many :completed_tasks

class Teacher < ActiveRecord::Base
 has_many :students
 has_many :tasks

class CompletedTask < ActiveRecord::Base
 belongs_to :student
 belongs_to :task

In my views, I want a teacher to be able to add Tasks for his/her students. When the Students view their Tasks, they see the Teacher's available tasks and can add their own. Students then mark the tasks as complete in a separate view. Should I consider using polymorphic association for this? My situation seems a bit different from how it's used in Ryan Bates' Railscast #154 since the Teacher and Student are interacting with the tasks in slightly different ways.

Upvotes: 2

Views: 722

Answers (1)

x1a4
x1a4

Reputation: 19485

I would use a polymorphic association on Task to denote the creator of the task. The association between Teacher and Task may be unnecessary, unless a teacher can have available tasks that were not created by them. If that's the case, keep the current association to teacher, but if not, you only need an association for the creator.

Instead of CompletedTask, I would use a class called Assignment, that belongs to both a task and a student, and also has a completed flag, that defaults to false. This allows for tracking which students are assigned which tasks, whether the tasks are ongoing or completed.

class Task < ActiveRecord::Base
  belongs_to :creator, :polymorphic => true

  has_many :assignments
  has_many :assigned_students, :through => :assignments, :source => :student
end

class Student < ActiveRecord::Base
  belongs_to :teacher
  has_many :created_tasks, :as => :creator, :class_name => 'Task'

  has_many :assignments
  has_many :assigned_tasks, :through => :assignments, :source => :task
end

class Teacher < ActiveRecord::Base
  has_many :students
  has_many :created_tasks, :as => :creator, :class_name => 'Task'
end

class Assignment < ActiveRecord::Base
  belongs_to :student
  belongs_to :task

  scope :complete, where(:completed => true)
  scope :incomplete, where(:completed => false)
end

Upvotes: 5

Related Questions