0

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:

  1. How can I fix the nested form to correctly populate submission_id for the answer?
  2. Is there another way I can go about this to accomplish the same thing?
  3. 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!!

yzi0148
  • 45
  • 1
  • 6
  • You know your requirements better than anyone...but I'm having trouble differentiating a `Work` from a `Submission`. I'd say get rid of one or the other, which will simplify your models. Maybe a submission is more of an action taken on a `Work` object – Mark Merritt Jun 04 '19 at 01:07
  • @izy May i know what have you tried so far? – Anand Jun 04 '19 at 03:42
  • I'm currently trying out Mark's suggestion and removing `Submission` and instead adding a column so that I know if the `Work` is created by a teacher or created by a student. I'm thinking of making [`Work` a self referential model](https://stackoverflow.com/questions/6097288/how-can-i-do-self-reference-with-ruby-on-rails) I've also tried a nested form using the Cocoon gem. `Submission` accepted attributes for `answers` and `questions`. `Work` also accepted attributes for questions. `Question` accepts attributes for `answers` – yzi0148 Jun 04 '19 at 03:44
  • @izy Question is not clear, can you show the form by which you want to pass parent_id, that may be helpful to figure out. – Anand Jun 04 '19 at 04:27

0 Answers0