我使用的是Rails 5.0.0.rc1,ruby 2.3.0p0,factory_girl(4.7.0),factory_girl_rails(4.7.0),faker(1.6.3)。
在我的控制台,我做&得到以下内容:
[1] pry(main)> q1 = FactoryGirl.create(:question)
(0.2ms) BEGIN
SQL (1.1ms) INSERT INTO "users" ("email", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["email", "vince@harris.com"], ["created_at", 2016-05-13 00:41:03 UTC], ["updated_at", 2016-05-13 00:41:03 UTC]]
(2.0ms) COMMIT
(0.1ms) BEGIN
SQL (0.4ms) INSERT INTO "users" ("email", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["email", "wilhelm.crona@luettgen.net"], ["created_at", 2016-05-13 00:41:04 UTC], ["updated_at", 2016-05-13 00:41:04 UTC]]
(1.4ms) COMMIT
(0.1ms) BEGIN
SQL (0.4ms) INSERT INTO "users" ("email", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["email", "marlen@boyer.name"], ["created_at", 2016-05-13 00:41:04 UTC], ["updated_at", 2016-05-13 00:41:04 UTC]]
(0.5ms) COMMIT
(0.2ms) BEGIN
SQL (0.3ms) INSERT INTO "users" ("email", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["email", "brain@medhurst.io"], ["created_at", 2016-05-13 00:41:04 UTC], ["updated_at", 2016-05-13 00:41:04 UTC]]
(0.3ms) COMMIT
(0.1ms) BEGIN
SQL (0.3ms) INSERT INTO "users" ("email", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["email", "rico.rowe@hudsonankunding.info"], ["created_at", 2016-05-13 00:41:04 UTC], ["updated_at", 2016-05-13 00:41:04 UTC]]
(0.3ms) COMMIT
(0.1ms) BEGIN
SQL (0.8ms) INSERT INTO "users" ("email", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["email", "zakary@ritchie.io"], ["created_at", 2016-05-13 00:41:04 UTC], ["updated_at", 2016-05-13 00:41:04 UTC]]
这是我的Question
工厂:
# == Schema Information
#
# Table name: questions
#
# id :integer not null, primary key
# title :string
# body :text
# user_id :integer
# accepted_answer_id :integer
# created_at :datetime not null
# updated_at :datetime not null
#
FactoryGirl.define do
factory :question do
user
association :accepted_answer, factory: :answer
title { Faker::Lorem.sentence(3, true, 4) }
body { Faker::Lorem.paragraphs(2, true) }
end
end
这是我的Question
模型:
# == Schema Information
#
# Table name: questions
#
# id :integer not null, primary key
# title :string
# body :text
# user_id :integer
# accepted_answer_id :integer
# created_at :datetime not null
# updated_at :datetime not null
#
class Question < ApplicationRecord
belongs_to :user
belongs_to :accepted_answer, class_name: "Answer"
has_many :answers
end
这是我的User
工厂:
# == Schema Information
#
# Table name: users
#
# id :integer not null, primary key
# email :string
# created_at :datetime not null
# updated_at :datetime not null
#
FactoryGirl.define do
factory :user do
email { Faker::Internet.email }
end
end
这是我的User
模型:
# == Schema Information
#
# Table name: users
#
# id :integer not null, primary key
# email :string
# created_at :datetime not null
# updated_at :datetime not null
#
class User < ApplicationRecord
has_many :questions
has_many :answers
end
修改1
这是我的Answer
工厂:
# == Schema Information
#
# Table name: answers
#
# id :integer not null, primary key
# body :text
# user_id :integer
# question_id :integer
# created_at :datetime not null
# updated_at :datetime not null
#
FactoryGirl.define do
factory :answer do
question
user
body { Faker::Lorem.paragraphs(2, true) }
end
end
这是我的Answer
模型:
# == Schema Information
#
# Table name: answers
#
# id :integer not null, primary key
# body :text
# user_id :integer
# question_id :integer
# created_at :datetime not null
# updated_at :datetime not null
#
class Answer < ApplicationRecord
belongs_to :question
belongs_to :user
end
什么可能导致无休止的用户创建循环?
答案 0 :(得分:2)
您的Question
和Answer
工厂之间存在循环依赖关系。
Question
构建了answer
关联,answer
关联构建了question
关联,而这种关联反过来构建了Answer
关联 - 无限制。
您在INSERT
上看到User
s无限追踪的原因是因为这是您当前实施问题工厂的第一件事,也是唯一的行动执行。它从来没有机会做任何其他事情,因为它陷入了无限的倒退。
与Dave的链接建议一样,最简单的解决方法可能是简单地使用after :build
或after :create
来延迟构建关联,直到创建父对象为止。您也可以省略在相应的工厂定义中声明answer
或question
引用,而不是在创建工厂时明确声明它们:
let(:question) { FactoryGirl.create(:question) }
let(:answer) { FactoryGirl.create(:answer, question: question) }
就个人而言,我更喜欢第二种方法,因为它的清晰度。它还可以以一些额外代码的低成本提供对测试套件的更大控制。
根据我的经验,明确了解如何在测试套件的初始化阶段定义测试数据是值得的。依赖FactoryGirl回调,约定和语法糖会导致意外行为和难以追查的混淆不一致。