我正在尝试编写一个验证,检查属于某个模型的嵌套属性之一是否包含某个值。
在这种情况下,我有一个包含许多答案的问题模型。我需要进行验证,检查是否至少有一个问题标记了正确答案。
这是一款用于创建测试的应用。这个问题有几个答案,但并非所有答案都是正确答案。
这是我的问题模型:
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。
我真的很喜欢这个作为验证工作。我只是不知道在保存之前如何访问嵌套属性。
这就是params的样子:
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"}
我也尝试使用params在控制器中执行此操作。这是我的创建函数的样子:
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
这实际上也不起作用。即使没有正确的答案,它仍然可以保存。无论如何,我不想在控制器中这样做。作为验证,它会更好。
我确定我在这里遗漏了一些明显的东西。任何人都可以帮助我吗?
答案 0 :(得分:0)
我明白了!
谢谢,Ashik。我不知道你可以使用这样的方法,即使数据不在数据库中。
我尝试了你的想法。它没有返回正确的结果,但非常接近。
answers.map {| x | x [:correct] == true} .size == 0?
返回所有Answers记录的正确属性数组。像这样:
[false, false, true]
我稍微改变了一下这个方法:
answers.map{ |x| x[:correct]}.include? true
如果任何记录包含正确的记录,则返回true。我在我的验证方法中尝试过,它运行得很好。
这是更新的问题模型。
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
answers.map{ |x| x[:correct]}.include? true
end
end