I have a schoolwork platform that allow:
- users to create a homework assignment (Work
) or quiz (Work
that has Questions
)
- users to submit assignments (Submission
)
A given assignment or work
, it can have many submissions
. A work
may also have many questions
. A question
can have many answers
, either canonical answers
(set by the teacher) or non-canonical answers
(submitted by students).
When a student submits an assignment (creates a Submission
for a given Work
), they should see the questions relating to the work and be able to create non-canonical answers
. A student should not be able to change any attributes of a question
.
Problem: I'm thinking of using a nested form to model the above behavior, but am having some trouble populating the correct fields. I need to be able to relate an answer back to the submission it came from. However, at the moment I submit the form and call Submission.new
/ Submission.create
, the submission doesn't have an ID yet and so I cannot populate the answers_attribute
with the submission_id
.
Question:
- How can I fix the nested form to correctly populate
submission_id
for the answer? - Is there another way I can go about this to accomplish the same thing?
- Is there a simpler way to design the relationships than what I have now?
Code
class Work < ApplicationRecord
has_many :submissions
has_many :questions # Allow for quizzes
has_many :answers, through: :questions
accepts_nested_attributes_for :questions, reject_if: :all_blank, allow_destroy: true
validates :name, presence: true, allow_nil: false
end
# == Schema Information
#
# Table name: works
#
# id :bigint(8) not null, primary key
# description :text
# due_date :datetime
# grades_published :boolean default(FALSE)
# name :string
# points :float default(1.0)
# published :boolean
# submittable :boolean default(TRUE)
# url :string
# created_at :datetime not null
# updated_at :datetime not null
# category_id :integer
# course_id :integer
#
class Submission < ApplicationRecord
belongs_to :work
belongs_to :enrollment
has_one :grade
has_many :questions, through: :works
has_many :answers, through: :questions
accepts_nested_attributes_for :questions, reject_if: :all_blank, allow_destroy: true
accepts_nested_attributes_for :answers, reject_if: :all_blank, allow_destroy: true
validates_uniqueness_of :work_id, scope: :enrollment_id, message: " has already been submitted"
end
# == Schema Information
#
# Table name: submissions
#
# id :bigint(8) not null, primary key
# enrollment_id :integer
# work_id :integer
# title :string
# content :text
# created_at :datetime not null
# updated_at :datetime not null
#
class Question < ApplicationRecord
belongs_to :work
has_many :answers, inverse_of: :question
accepts_nested_attributes_for :answers, reject_if: :all_blank, allow_destroy: true
validates :value, presence: true, allow_nil: false
end
# == Schema Information
#
# Table name: questions
#
# id :bigint(8) not null, primary key
# value :string
# created_at :datetime not null
# updated_at :datetime not null
# work_id :bigint(8)
#
# Indexes
#
# index_questions_on_work_id (work_id)
#
class Answer < ApplicationRecord
belongs_to :question, inverse_of: :answers
# belongs_to :work, through: :questions
# belongs_to :submission, through: :works
validates :question_id, :presence => true
validates :value, presence: true, allow_nil: false
end
# == Schema Information
#
# Table name: answers
#
# id :bigint(8) not null, primary key
# is_canon :boolean default(FALSE)
# is_correct :boolean default(FALSE)
# value :string
# created_at :datetime not null
# updated_at :datetime not null
# question_id :bigint(8)
# submission_id :bigint(8)
#
# Indexes
#
# index_answers_on_question_id (question_id)
# index_answers_on_submission_id (submission_id)
#
# Foreign Keys
#
# fk_rails_... (question_id => questions.id)
# fk_rails_... (submission_id => submissions.id)
#
Help is very much appreciated. Thank you!!