验证是否有任何嵌套属性包含值

时间:2018-03-05 06:16:36

标签: ruby-on-rails validation nested-attributes

我正在尝试编写一个验证,检查属于某个模型的嵌套属性之一是否包含某个值。

在这种情况下,我有一个包含许多答案的问题模型。我需要进行验证,检查是否至少有一个问题标记了正确答案。

这是一款用于创建测试的应用。这个问题有几个答案,但并非所有答案都是正确答案。

这是我的问题模型:

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

这实际上也不起作用。即使没有正确的答案,它仍然可以保存。无论如何,我不想在控制器中这样做。作为验证,它会更好。

我确定我在这里遗漏了一些明显的东西。任何人都可以帮助我吗?

1 个答案:

答案 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