FactoryBot-创建嵌套对象

时间:2018-07-15 20:02:38

标签: ruby-on-rails rspec capybara

我正在学习如何在Rails中进行测试,并且正在为我的问题模型编写工厂:

require 'factory_bot'

FactoryBot.define do
  factory :question do
    sequence(:content) { |n| "question#{n}" }
    source "BBC"
    year "1999"
  end
end 

问题是我有一个has_many :choices关系,应该为我的问题选择5个选择。所以我想知道如何在工厂机器人上做到这一点。不要从文档中得到它,因此将不胜感激。谢谢!

这是我的问题模型:

class Question < ApplicationRecord

  belongs_to :question_status
  belongs_to :user
  has_many :choices

    accepts_nested_attributes_for :choices, limit: 5

  validates :content, :source, :year, presence: true
  validate :check_number_of_choices,


  def check_number_of_choices
    if self.choices.size != 5
        self.errors.add :choices, I18n.t("errors.messages.number_of_choices")
    end
  end

end

我的选择模型:

class Choice < ApplicationRecord

  belongs_to :question

  validates :content, presence: true, allow_blank: false


end

我的工厂代码:

FactoryBot.define do

    factory :question_status do
        name "Pending"
    end

  factory :choice do
    sequence(:content) { |n| "choice #{n}" }
    question
  end


  factory :question do
    sequence(:content) { |n| "question #{n}" }
    source "BBC"
    year "1999"
    user
    question_status

        before :create do |question|
        create_list :choice, 5, question: question
    end

  end

end 

还有我的功能测试(它仍然不执行任何操作,但是由于我的验证,它已经无法创建问题):

require 'rails_helper'

RSpec.feature "Evaluating Questions" do

    before do
        puts "before"
        @john = FactoryBot.create(:user)
        login_as(@john, :scope => :user)
        @questions = FactoryBot.create_list(:question, 5)
        visit questions_path
    end


    scenario "A user evaluates a question correctly" do
        puts "scenario"
    end


end

1 个答案:

答案 0 :(得分:3)

这里可能发生的事是在select集合代理中使用choices导致Rails在验证期间尝试再次从数据库加载集合,但尚未持久化。尝试从验证中删除select

if self.choices.size != 5

由于select模型已经验证了必须存在内容,因此实际上可能根本不需要Choice。构建列表时,您可能还需要将选择分配给问题

before :create do |question|
  question.choices = build_list :choice, 5, question: question
end