【发布时间】:2018-03-05 06:16:35
【问题描述】:
我正在尝试编写一个验证来检查属于模型的嵌套属性之一是否包含某个值。
在这种情况下,我有一个包含许多答案的问题模型。我需要一个验证来检查是否至少有一个问题标记了正确答案。
这是一个用于创建测试的应用程序。这个问题有几个答案,但并非所有答案都是正确的。
这是我的问题模型:
class Question < ApplicationRecord
belongs_to :examination
has_many :answers, dependent: :destroy
has_many :responses
accepts_nested_attributes_for :answers, allow_destroy: true, :reject_if => :all_blank
validates_presence_of :body
validates_presence_of :question_type
validate :has_correct_ans?
private
def has_correct_ans?
errors.add(:correct, "You must select at least one correct answer") unless
self.answers.exists?(correct: true)
end
end
这是答案模型
class Answer < ApplicationRecord
belongs_to :question
has_many :responses, dependent: :destroy
end
我试图编写一个名为“has_correct_ans?”的方法检查任何答案是否包含正确的属性。但这每次都失败。我认为这是因为在保存之前数据库中不存在数据。通过在控制台中进行测试,该命令在现有数据上运行良好。
即Question.find.answers.exists?(correct: true)
对于其中一个答案具有正确属性的问题将返回 true。
我真的很喜欢这样作为验证。我只是不知道如何在保存之前访问嵌套属性。
这是参数的样子:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"dOf8H1Wqark3TZAGgX6kaY5Yt4kYKm1FNbCnNi4BlVTTQV9PijlkA1bNS8Qi8DwLLxV6FkWzNbmiT6X+7Vr6Xg==", "question"=>{"body"=>"gfdgdfs", "question_type"=>"Multiple Choice", "points"=>"1", "answers_attributes"=>{"0"=>{"correct"=>"true", "body"=>"dggf", "_destroy"=>"0"}}}, "commit"=>"Submit", "examination_id"=>"12"}
我也尝试使用参数在控制器中执行此操作。这是我的创建函数的样子:
class QuestionsController < ApplicationController
def create
@exam = Examination.find(params[:examination_id])
@question = @exam.questions.build(question_params)
ans_params = params[:question][:answers_attributes]
@correct_ans = false
ans_params.each do |k, v|
if @correct_ans == false
@correct_ans = v.has_key?(:correct)
end
end
if @exam.questions.count > 0
@question.position = @exam.questions.count + 1
else
@question.position = 1
end
if @correct_ans == true && @question.save
redirect_to @exam, notice: "question created successfully"
elsif @question.save
flash[:error] = "You need a correct answer"
render :new
else
render :new
end
end
这实际上也不起作用。即使没有正确答案,它仍然可以保存。无论如何,我不想在控制器中这样做。作为验证,它会更好。
我确定我在这里遗漏了一些明显的东西。谁能帮帮我?
【问题讨论】:
-
抱歉,目前无法在控制台查看。也许
errors.add(...) if answers.where(correct: true).size == 0? -
这与我在该方法中的效果相同。刚刚试了一下。
-
试试这个:
errors.add(...) if answers.map{ |x| x[:correct] == true }.size == 0?你不能在这里使用 where 查询,因为它会触发数据库调用并且不存在记录。您可以使用任何其他方法来获取数据而无需调用数据库,因为它没有插入数据库(验证阶段)。在这里,我使用 map 来实现相同的目的。您可以根据需要使用任何其他方法!
标签: ruby-on-rails validation nested-attributes