2016-05-13 16 views
0

Ich benutze Rails 5.0.0.rc1, Ruby 2.3.0p0, Factory_Girl (4.7.0), Factory_Girl_Rails (4.7.0), Faker (1.6.3).Warum bleibt meine FactoryGirl-Methode in einer Endlosschleife stecken?

An meiner Konsole, ich die folgende & erhalten:

[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]] 

Hier ist meine Question Fabrik:

# == 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 

Hier ist mein Question Modell:

# == 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 

Hier meine User Fabrik:

# == 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 

Hier ist mein User Modell:

# == 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 

bearbeiten 1

Hier ist meine Answer Fabrik:

# == 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 

Hier ist mein Answer Modell:

# == 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 

Was könnte diese endlose Benutzererstellungsschleife verursachen?

+2

Lassen Sie uns Ihre Antwort Fabrik sehen. –

+0

Mögliches Duplikat von [FactoryGirl Circular Abhängigkeit und Validierung] (http://stackoverflow.com/questions/21255253/factorygirl-circular-dependency-and-validation) –

+0

@DaveSchweisguth Ich habe die Answer factory hinzugefügt. – marcamillion

Antwort

2

Sie haben eine zirkuläre Abhängigkeit zwischen Ihren Question und Answer Fabriken.

Question baut eine answer Vereinigung und der answer Verein baut eine question Vereinigung, die wiederum baut eine Answer Verein - ad infinitum.

Der Grund, warum Sie eine unendliche Spur von INSERT s auf User sehen, liegt daran, dass dies die erste und einzige Aktion ist, die Ihre aktuelle Implementierung der Question-Factory ausführen kann. Es hat nie die Möglichkeit, etwas anderes zu tun, weil es in einem unendlichen Regress feststeckt.

Wie Daves Link suggeriert, kann die einfachste Lösung darin bestehen, einfach after :build oder after :create zu verwenden, um den Aufbau der Assoziation zu verzögern, bis das Elternobjekt erstellt ist. Sie können auch die answer oder question Referenzen in den entsprechenden Fabrik Definitionen anstelle weglassen erklärt sie ausdrücklich erklären, wenn Sie die Fabrik selbst erstellen:

let(:question) { FactoryGirl.create(:question) } 
let(:answer) { FactoryGirl.create(:answer, question: question) } 

Ich persönlich ziehe den zweiten Ansatz für sie Klarheit ist. Es bietet auch eine bessere Kontrolle über Ihre Testsuite bei geringen Kosten für zusätzlichen Code.

Meiner Erfahrung nach lohnt es sich, explizit zu erläutern, wie Ihre Testdaten in den Initialisierungsphasen Ihrer Testsuite definiert werden. Sich auf FactoryGirl Callbacks, Konventionen und syntaktischen Zucker zu verlassen, kann zu unerwartetem Verhalten und verwirrenden Inkonsistenzen führen, die schwer zu verfolgen sind.