Как передать ссылочный / родительский идентификатор в полиморфную дочернюю запись через вложенную форму? - PullRequest
1 голос
/ 27 мая 2019

У меня двойная вложенная форма, и мне нужно сохранить ID одного из родителей в записи о ребенке. Однако родительская запись может еще не иметь идентификатора, поэтому я не могу сохранить этот идентификатор. Как я могу передать этот ссылочный идентификатор? Спасибо!

Контекст

Я немного новичок в Rails и работаю над приложением домашней работы, где учитель может создать Work. Work может иметь Questions, а Question - Answers. За Work студент может создать Submission. Submission может иметь Answers (что является ответом на вопросы Work.

Цель В конечном счете, я хотел бы отобразить информацию для представления учащегося, включая соответствующую Work информацию, Answers предоставленную учащимся вместе с Question, на который они отвечали.

В настоящее время я не могу создать Answer и указать в нем идентификатор Question, в который он вложен (что имеет смысл для меня, поскольку при отправке формы Question может не существовать и выиграть) у меня нет идентификатора.

Мои вопросы:

  1. Как я могу передать родителя / ссылку question_id в answer?
  2. Если это невозможно, как я могу реорганизовать эти модели, чтобы я смог достичь поставленной цели?
  3. Является ли полиморфизм лучшим вариантом здесь, или я должен использовать ИППП? (Или это не относится к моему делу)

код

Мои модели:

модель / work.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
#

модель / submission.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
#

Модели / question.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)
#

модель / answer.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)
#

Контроллер

* +1058 * Контроллер / works_controller.rb
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

Просмотров: 1062 * * _form.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' _question_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" _answer_fields.html.slim .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 routes.rb 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 отношениями модели. class Question < ApplicationRecord ... has_many :answers, as: :answerable, inverse_of: :question ... end Я также рассмотрел возможность выделения формы таким образом, чтобы Question / Answer создавались не при отправке формы, а скорее как запрос AJAX, чтобы я мог получить question_id. При отправке формы звоните questions_controller (что вызывает answers_controller), и каждый из них создает свои собственные записи, а не создает все в пределах works_controller TLDR У меня двойная вложенная форма, и мне нужно сохранить ID одного из родителей в записи о ребенке. Однако родительская запись может еще не иметь идентификатора, поэтому я не могу сохранить этот идентификатор. Как я могу передать этот ссылочный идентификатор? Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...