Rails 5:如何将父资源的属性传递给嵌套资源?

时间:2018-10-15 13:10:07

标签: ruby-on-rails

我有一个模型MultipleChoiceQuestion,它具有五个属性:answer_oneanswer_twoanswer_threeanswer_fouranswer_five,以及一个名为answer_correct

的字段

我想跟踪每个用户加载每个问题后选择 onClick 的情况。可能使用远程:是的-我一直在互联网上阅读,似乎很容易创建一个名为UserAnswer的嵌套多态模型,以跟踪用户对每个问题的答案选择。

但是,我感到困惑的是如何将原始模型的参数(MultipleChoiceQuestion)传递给视图中的新模型,因为我的理解是所有模型在数据库中都有不同的属性。 (当信息字符串来自父模型时,我如何确保我可以保留用户通过第二模型单击时选择的内容?)

是否可以将父模型的属性传递给嵌套模型?这样做的目的是让用户随着时间的流逝了解自己的正确或错误。

MultipleChoiceQuestion.rb模型

# == Schema Information
#
# Table name: multiple_choice_questions
#
#  id                                         :bigint(8)        not null, primary key
#  question                                   :text
#  answer_one                                 :text
#  answer_two                                 :text
#  answer_three                               :text
#  answer_four                                :text
#  answer_correct                             :text
#  answer_explanation                         :text
#  published                                  :boolean
#  flagged                                    :boolean
#  user_id                                    :bigint(8)
#  created_at                                 :datetime         not null
#  updated_at                                 :datetime         not null
#  slug                                       :string           not null
#  source                                     :string
#  reviewed                                   :boolean
#  who_reviewed                               :string
#  reviewed_at                                :datetime
#  difficulty_rating                          :integer
#  multiple_choice_question_classification_id :integer
#  controversial                              :boolean          default(FALSE)
#  origination                                :integer          default("not_given")

Class MultipleChoiceQuestion < ApplicationRecord
  belongs_to :user, optional: true
  validates :user, presence: true

  belongs_to :multiple_choice_question_classification, optional: true

  has_many :flags, dependent: :destroy

  acts_as_taggable

  # activity feed
  include PublicActivity::Model
  tracked owner: Proc.new { |controller, model| controller.current_user ? controller.current_user : nil }

  validates :question, :slug, presence: true, length: { minimum: 5 }
  validates_uniqueness_of :question

User.rb模型

# == Schema Information
#
# Table name: users
#
#  id                     :bigint(8)        not null, primary key
#  email                  :string           default(""), not null
#  encrypted_password     :string           default(""), not null
#  reset_password_token   :string
#  reset_password_sent_at :datetime
#  remember_created_at    :datetime
#  sign_in_count          :integer          default(0), not null
#  current_sign_in_at     :datetime
#  last_sign_in_at        :datetime
#  current_sign_in_ip     :string
#  last_sign_in_ip        :string
#  created_at             :datetime         not null
#  updated_at             :datetime         not null
#  first_name             :string
#  last_name              :string
#  school_name            :string
#  graduation_year        :string
#  current_sign_in_token  :string
#  admin                  :boolean          default(FALSE)
#  superadmin             :boolean          default(FALSE)
#  verified               :boolean          default(FALSE)
#  premiumuser            :boolean          default(FALSE)
#  regularuser            :boolean          default(FALSE)
#  banneduser             :boolean          default(FALSE)
#  user_role              :boolean          default(TRUE)
#  username               :string           default(""), not null
class User < ApplicationRecord
  has_many :posts, dependent: :destroy
  has_many :multiple_choice_questions, dependent: :destroy
  has_many :comments, dependent: :destroy

  has_many :flags
  has_many :saved_items

  has_one_attached :avatar

查看-multiple_choice_questions / show.html.erb

<h5>
    <%= @multiple_choice_question.question %>
  </h5>

  <p>
    <span>Answer choice #1:</span>
    <%= @multiple_choice_question.answer_one %>
  </p>

  <p>
    <span>Answer choice #2:</span>
    <%= @multiple_choice_question.answer_two %>
  </p>

  <p>
    <span>Answer choice #3:</span>
    <%= @multiple_choice_question.answer_three %>
  </p>

  <p>
    <span>Answer choice #4:</span>
    <%= @multiple_choice_question.answer_four %>
  </p>

  <p class="correct">
    <span>Correct Answer:</span>
    <%= @multiple_choice_question.answer_correct %>
  </p>

2 个答案:

答案 0 :(得分:1)

这就是我要做的:

首先,您需要对考试或测试有某种参考。 其次,您的考试需要有x个问题。 第三,您的问题需要有x个可能的答案以及一个正确的答案。然后,采用您的用户模型,并将该用户与这样的测试和答案相关联。

请注意,这不是有效的语法,仅用于说明目的。

class Exam has_many :questions
           has_and_belongs_to_many :users

class Question has_many :answers
               has_many :user_answers
               belongs_to :exam

class Answer belongs_to :question

class UserAnswer belongs_to :question
                 belongs_to :user

class User has_and_belongs_to_many :exams
           has_many :user_answes

现在,您可以将任何考试与任何用户相关联,也可以将任何答案与任何用户相关联。

例如,如果您向Answers控制器提交表单,则可以创建关联来跟踪每个用户先前选择的答案,就像这样:

            answer = Answer.find(params[:id])
            user_answer = UserAnswer.create(answer_id: answer.id, user_id: user.id, question_id: answer.question.id)

因此,现在您可以将自己的UserExamUserAnswer模型进行相当大的连接,以提取用户针对特定考试给出的每个答案。如果您使用当前的模型结构,可以达到目标,但是它的可伸缩性将不那么理想,您可能必须四处寻找才能使其中的某些功能按您的意愿工作。

答案 1 :(得分:1)

如果您愿意保留当前的架构,则可能需要执行以下步骤来实现所需的功能

步骤 :(代码段会根据与OP的讨论进行更新)

1)定义一个自定义路线,您可以在 AJAX 中使用它来发送用户选择的答案并接收结果。

var base_string = '1,4,1,7,2';
base_string = base_string.split(',');

var new_string = []; 
for(var i=0; i<base_string.length-1; i++){
   if(base_string[i+1]>base_string[i]){
     for(var j=parseInt(base_string[i]); j<parseInt(base_string[i+1]); j+=.5){
         new_string.push((j))
     }
   }
  else  if(base_string[i+1]<base_string[i]){
     for(var j=parseInt(base_string[i]); j>=parseInt(base_string[i+1]); j-=.5){
         new_string.push((j))
     }
   }
}
console.log("new_string: "+new_string);

2)具有链接的答案,以便用户点击

#routes.rb
post '/verify_user_selected_answer', to: "multiple_choice_questions#verify_user_selected_answer'

3)用户单击答案时触发 AJAX 呼叫

<%= link_to @multiple_choice_question.answer_one, "javascript:void(0);", class: "answer" %>

4)使用$(document).ready(function() { $("a.answer").on( "click", function( event ) { var current_answer = $(this); var question_id = '<%= @multiple_choice_question.id %>'; var current_user = "<%= current_user.id %>"; $.ajax({ url: "/verify_user_selected_answer", type: "POST", dataType: "json", data: {user_id: current_user, question: question_id, answer: current_answer.text()}, success: function(response){ $("#display_result").text(response["result"]); } }); }); }); 来显示结果。

div

5)最后,在<div id="display_result">中执行验证并发送回结果

multiple_choice_questions#verify_user_selected_answer