2016-05-13 3 views
0

私はRails 5.0.0.rc1、ruby 2.3.0p0、factory_girl(4.7.0)、factory_girl_rails(4.7.0)、faker(1.6.3)を使用しています。私のコンソールでFactoryGirlの作成メソッドが無限ループに陥るのはなぜですか?

、私&は以下で入手できます:ここで

[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", "[email protected]"], ["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", "[email protected]"], ["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", "[email protected]"], ["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", "[email protected]"], ["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", "[email protected]"], ["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", "[email protected]"], ["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 
# 

class Question < ApplicationRecord 
    belongs_to :user 
    belongs_to :accepted_answer, class_name: "Answer" 
    has_many :answers 
end 

されています。ここでは

# == 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モデルです私の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 

エンドユーザ作成ループを引き起こす原因は何ですか?

+2

Answerファクトリーを見てみましょう。 –

+0

[FactoryGirlの循環依存関係と検証]の可能な複製(0120-337-002) –

+0

@DaveSchweisguth Answerファクトリを追加しました。 – marcamillion

答えて

2

お客様のQuestionAnswer工場の間には循環的な依存関係があります。

Questionanswer関連付けを構築し、answer協会は、順番に、Answer協会のビルドquestion協会構築する - 無限に。

INSERTの無限のトレースがUserにあるのは、これがQuestion Factoryの現在の実装が実行できる最初のことと唯一の動作だからです。それは無限回帰に詰まっているので、決して他のことをする機会がありません。

Daveさんのリンクにもあるように、最も簡単な解決策は、親オブジェクトが作成されるまで、after :buildまたはafter :createを使用して関連付けの作成を延期することです。それは明快だために、私は多くの第二のアプローチを好む、

let(:question) { FactoryGirl.create(:question) } 
let(:answer) { FactoryGirl.create(:answer, question: question) } 
個人的に

:また、あなたは工場自体を作成するときに明示的に宣言するの代わりに対応する工場の定義でanswerまたはquestion参照を宣言省略することができます。また、いくつかの追加コードのわずかなコストで、テストスイートをより詳細に制御することができます。

私の経験では、テストスイートの初期化段階でテストデータがどのように定義されているかを明示することは価値があります。 FactoryGirlのコールバック、表記法、および構文的な砂糖に依存すると、予想外の動作とトレースが困難な混乱した不一致が発生する可能性があります。

関連する問題