如何通过嵌套形式将引用/父ID传递到多态子记录中?

时间:2019-05-27 01:24:22

标签: ruby-on-rails ruby model-view-controller activerecord polymorphism

我有一个双嵌套表格,我需要在孩子记录中保存其中一位父母的ID。但是,父记录可能还没有ID,因此我无法保存ID。如何传递这个参考ID?谢谢!

上下文

我对Rails还是陌生的,正在开发一个家庭作业应用程序,老师可以创建一个WorkWork可以具有Questions,而Question可以具有Answers。 对于Work,学生可以创建SubmissionSubmission可以有Answers(这是对Work的问题的答复。

目标,最终,我想显示学生提交的信息,包括相关的Work信息,Answers与{{1} }他们正在回答。

我目前无法创建Question并使其引用嵌套的Answer的ID(这对我来说很有意义,因为在提交表单时,Question可能不存在,并且没有ID。

我的问题是:

  1. 如何将父项/引用的Question传递到question_id中?
  2. 如果这不可能,那么我应该如何重组这些模型,以便实现上述目标?
  3. 多态性是此处的最佳使用方法还是应该使用STI? (或者这与我的情况无关)

代码

我的模特:

models / work.rb

answer

models / submission.rb

class Work < ApplicationRecord
  has_many :submissions
  has_many :questions # Allow for quizzes
  accepts_nested_attributes_for :questions, reject_if: :all_blank, allow_destroy: true
end
# == Schema Information
#
# Table name: works
#
#  id               :bigint(8)        not null, primary key
#  description      :text
#  due_date         :datetime
#  name             :string
#  submittable      :boolean          default(TRUE)
#  url              :string
#  created_at       :datetime         not null
#  updated_at       :datetime         not null
#  course_id        :integer
#

models / question.rb

class Submission < ApplicationRecord
  belongs_to :work
  has_many :answers, as: :answerable
  accepts_nested_attributes_for :answers, reject_if: :all_blank, allow_destroy: true
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
#

models / answer.rb

class Question < ApplicationRecord
  belongs_to :work
  has_many :answers, as: :answerable
  # has_many :answers, as: :answerable, 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)
#

控制器

controller / works_controller.rb

class Answer < ApplicationRecord
  belongs_to :answerable, polymorphic: true

  validates :value, presence: true, allow_nil: false
end

# == Schema Information
#
# Table name: answers
#
#  id              :bigint(8)        not null, primary key
#  answerable_type :string
#  is_canon        :boolean          default(FALSE)
#  is_correct      :boolean          default(FALSE)
#  value           :string
#  created_at      :datetime         not null
#  updated_at      :datetime         not null
#  answerable_id   :bigint(8)
#  question_id     :bigint(8)
#
# Indexes
#
#  index_answers_on_answerable_id  (answerable_id)
#  index_answers_on_question_id    (question_id)
#
# Foreign Keys
#
#  fk_rails_...  (question_id => questions.id)
#

观看次数:

_form.html.slim

class WorksController < ApplicationController

  def create
    @work = Work.new(work_params)

    respond_to do |format|
      if @work.save
        format.html { redirect_to @work, notice: 'Work was successfully created.' }
        format.json { render :show, status: :created, location: @work }
      else
        format.html { render :new }
        format.json { render json: @work.errors, status: :unprocessable_entity }
      end
    end
  end
  private

    def work_params
      params.require(:work).permit(:name, :category_id, :course_id, :description, :url, :due_date, :published, :points, :grades_published,

        questions_attributes: [:id, :value, :_destroy,

          answers_attributes: [:id, :value, :question_id, :is_correct, :is_canon, :_destroy]

        ]

      )

    end

end

_question_fields.html.slim

...
  / Questions
  .form-group.u-mt2x
    = form.fields_for :questions do |question|
      = render 'shared/question_fields', f: question
    .links
      = link_to_add_association 'Add Question', form, :questions, class: "u-button--New u-button--sm", partial: 'shared/question_fields'

_answer_fields.html.slim

.nested-fields
  .form-group
    .form-group
      = f.label :value, "Question", :class => "required"
      = link_to_remove_association "remove question", f, data: {confirm: 'Are you sure you want to remove this question?'}
    = f.text_field :value, class: "form-control"

  // Answers / Choices
  .form-group.u-mt2x
    = f.fields_for :answers do |answer|
      = render 'shared/answer_fields', f: answer
    .links
      = link_to_add_association 'Add Choice', f, :answers, partial: "shared/answer_fields"

routes.rb

.nested-fields
  .form-group
    .form-group
      = f.label :value, "Answer Choice", :class => "required"
      = link_to_remove_association "remove choice", f, data: {confirm: 'Are you sure you want to remove this answer?'}
    = f.text_field :value, class: "form-control"
  .form-group
    = f.label :is_correct, "This is the correct answer"
    div
      = f.label :is_correct, "Yes", value: true
      = f.radio_button :is_correct, true
      = f.label :is_correct, "No", value: false
      = f.radio_button :is_correct, false
    /= f.select :is_correct, options_for_select([["Yes", true], ["No", false]])
  // Hidden fields
  .form-group
    - if current_user.id == @work.course.owner.id
      = f.label :is_canon, "Canonical Choice"
    = f.hidden_field :is_canon, value: current_user.id == @work.course.owner.id, :readonly => true
  /.form-group
    - if current_user.id == @work.course.owner.id
      = f.label :question_id, "Question ID"
    = f.text_field :question_id, @question.id

我尝试过/考虑过的内容

  1. Rails.application.routes.draw do resources :submissions ... devise_for :users, :path => 'auth', :controllers => {:registrations => "registrations"} get "works/index" resources :works do member do put 'toggle_publish' put 'toggle_publish_grades' end end ... root 'home#index' end 模型中添加inverse_of给了我Question,此外,ArgumentError (When assigning attributes, you must pass a hash as an argument.)似乎不适用于inverse_of模型关系。
polymorphic
  1. 我还考虑过分离表单,使得class Question < ApplicationRecord ... has_many :answers, as: :answerable, inverse_of: :question ... end / Question不是在表单提交时创建的,而是在AJAX请求中创建的,以便我可以获取{{1} }。

  2. 在提交表单时,呼叫Answer(呼叫question_id)并让每个成员创建自己的记录,而不是在questions_controller

  3. 中创建所有内容

TLDR

我有一个双嵌套表格,我需要在孩子记录中保存其中一位父母的ID。但是,父记录可能还没有ID,因此我无法保存ID。如何传递这个参考ID?谢谢!

0 个答案:

没有答案