2011-09-20 18 views
7

Sto utilizzando Ruby on Rails 3.0.9, RSpec-rails 2 e FactoryGirl. Sto cercando di stabilire un modello di associazione di fabbrica, ma sono nei guai.Problema modello associazione FactoryGirl: "SystemStackError: livello di stack troppo profondo"

Ho un file factories/user.rb come il seguente:

FactoryGirl.define do 
    factory :user, :class => User do 
    attribute_1 
    attribute_2 
    ... 

    association :account, :factory => :users_account, :method => :build, :email => '[email protected]' 
    end 
end 

e un file factories/users/account.rb come il seguente:

FactoryGirl.define do 
    factory :users_account, :class => Users::Account do 
    sequence(:email) {|n| "foo#{n}@bar.com" } 
    ... 
    end 
end 

L'esempio precedente funziona come previsto nei miei file spec, ma se nell'istruzione factory :users_account aggiungo il codice association :user in modo da avere

FactoryGirl.define do 
    factory :users_account, :class => Users::Account do 
    sequence(:email) {|n| "foo#{n}@bar.com" } 
    ... 
    association  :user 
    end 
end 

ottengo il seguente errore:

Failure/Error: Unable to find matching line from backtrace 
SystemStackError: 
    stack level too deep 

Come posso risolvere il problema in modo di accesso associato modelli da entrambe le parti \ fabbriche (vale a dire, nei miei file spec vorrei usare associazione RoR metodi modello come user.account e account.user) ?

P.S .: Ho letto la domanda Factory Girl and has_one e il mio caso è molto vicino al caso spiegato nella domanda collegata. Cioè, ho anche un'associazione has_one (tra le classi User e Users::Account).

+0

Semplicemente curioso, si dispone di un 'utente' e quindi si dispone di un' utente :: account', si suppone che sia plurale o dovrebbe essere 'Utente :: Account' o errore di battitura? – nowk

+0

@kwon - Non è un errore di battitura. Ho una classe 'Utenti :: Account'. – Backo

risposta

14

Secondo the docs, non è possibile inserire entrambi i lati delle associazioni nelle fabbriche. Avrai bisogno di usare il loro dopo richiamata per impostare un oggetto (i) da restituire.

Ad esempio, nel file factories/users/account.rb, è mettere qualcosa come

after(:build) do |user_account, evaluator| 
    user_account.user = FactoryGirl.build(:user, :account=>user_account) 
end 

Per le associazioni has_many, avrete bisogno di usare le loro funzioni * _List.

after(:build) do |user_account, evaluator| 
    user_account.users = FactoryGirl.build_list(:user, 5, :account=>user_account) 
end 

Nota: Credo l'esempio nella documentazione è un po 'fuorviante che non assegna nulla per l'oggetto. Credo che dovrebbe essere qualcosa di simile (notare il compito).

# the after(:create) yields two values; the user instance itself and the 
# evaluator, which stores all values from the factory, including ignored 
# attributes; `create_list`'s second argument is the number of records 
# to create and we make sure the user is associated properly to the post 
after(:create) do |user, evaluator| 
    user.posts = FactoryGirl.create_list(:post, evaluator.posts_count, user: user) 
end 
Problemi correlati