2011-09-20 7 views
7

Estoy usando Ruby on Rails 3.0.9, RSpec-rails 2 y FactoryGirl. Estoy tratando de establecer un modelo de asociación de Fábrica, pero estoy en problemas.Problema del modelo de asociación FactoryGirl: "SystemStackError: stack level too deep"

Tengo un archivo factories/user.rb como la siguiente:

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

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

y un archivo factories/users/account.rb como la siguiente:

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

El ejemplo anterior funciona como se esperaba en mis archivos de especificaciones, pero si en la declaración factory :users_account agrego el código association :user para tener

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

me sale el siguiente error:

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

¿Cómo puedo resolver ese problema, de modo que los modelos de acceso asociada de ambos lados \ fábricas (es decir, en mis archivos spec me gusta usar asociación RoR métodos modelo como user.account y account.user) ?

P.S .: Leí la pregunta Factory Girl and has_one y mi caso está muy cerca del caso explicado en la pregunta vinculada. Es decir, tengo una asociación has_one también (entre las clases User y Users::Account).

+0

Simplemente curioso, usted tiene un 'Usuario' y luego tiene una' Users :: Account', ¿se supone que es plural o debería ser 'User :: Account' o un error tipográfico? – nowk

+0

@kwon - No es un error tipográfico. Tengo una clase 'Users :: Account'. – Backo

Respuesta

14

De acuerdo con the docs, no puede simplemente poner ambos lados de las asociaciones en las fábricas. Tendrá que usar su devolución de llamada después de establecer un objeto (s) para devolver.

Por ejemplo, en el archivo factories/users/account.rb, se pone algo así como

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

Para las asociaciones has_many, tendrá que utilizar sus funciones _list *.

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

Nota: Creo que el ejemplo de los documentos es un poco engañoso que no asigna nada al objeto. Creo que debería ser algo así como (tenga en cuenta la tarea).

# 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 
Cuestiones relacionadas