子对象验证,至少一个具有给定值

时间:2019-06-27 14:09:48

标签: ruby-on-rails ruby-on-rails-5

我正在实现类似测验的功能。每个测验由几个问题组成,每个问题有3个可能的答案。

我需要确保每个问题至少有一个正确答案。

我的代码如下:

AssessmentQuestion.rb(型号)

has_many :assessment_options, inverse_of: :assessment_question, autosave: true
accepts_nested_attributes_for :assessment_options

(...)

validate :has_correct_answer

(...)

  def has_correct_answer
    errors.add(:question, "no correct answer") unless self.assessment_options.exists?(is_correct: true)
  end

不幸的是,此验证不起作用-会引发错误(即使存在assessment_option且答案正确的情况下,“也没有正确答案”。

更新(有关NM Pennypacker问题的答案):

AssessmentQuestionsController.rb

def new
    params[:course_id].present? ? edited_course : all_courses
    @assessment_question = AssessmentQuestion.new
        3.times {@assessment_question.assessment_options.build}
  end
  def create
    @assessment_question = AssessmentQuestion.new(assessment_question_params)
     if @assessment_question.save
       redirect_to course_path(assessment_question_params[:course_id]), notice: 'Assessment question was successfully created.'
     else
       params[:course_id].present? ? edited_course : all_courses
       render :new
     end
  end

_form.htm.erb

之后将添加

assessment_options

  <%= form.fields_for :assessment_options do |ao| %>

更新(有关EmilioMenéndez问题的答案):

assessment_question_params

    def assessment_question_params
      params.require(:assessment_question).permit(:id, :question, :course_id, :active,
        { assessment_options_attributes: [:id, :assessment_question_id, :answer, :is_correct] } )
    end

2 个答案:

答案 0 :(得分:0)

我最近在Rails 5.2应用中也遇到了这个问题。似乎strong_parametersaccepts_nested_attributes_for不兼容,如此处文档所述:https://edgeapi.rubyonrails.org/classes/ActionController/StrongParameters.html

就我而言,我不得不将my_model_attributes: []换成my_model: [],所以就您而言:

def assessment_question_params
  params.require(:assessment_question).permit(
    :id,
    :question,
    :course_id,
    :active,
    { 
      assessment_options: [
        :id,
        :assessment_question_id,
        :answer,
        :is_correct
      ]
    } 
  )
end

答案 1 :(得分:0)

根本原因是以下语句始终返回false-可能是因为尚未保存对象。

self.assessment_options.exists?(is_correct: true)

要解决此问题,我必须如下修改has_correct_answer:

  def has_correct_answer
    errors.add(:question, "no correct answer") unless self.assessment_options.select { |o| o.is_correct == true}.count > 0
  end

有更好的主意/解决方案吗?