2011-09-20 9 views
7

Ruby on Rails 3.0.9、RSpec-rails 2、FactoryGirlを使用しています。私は工場協会モデルを述べようとしていますが、私は困っています。FactoryGirlアソシエーションモデルのトラブル:「SystemStackError:スタックレベルが深すぎます」

私は、次のようなfactories/user.rbのファイルがあります:

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

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

をし、次のようなfactories/users/account.rbファイル:

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

上記の例では、私のスペックファイルで期待どおりに動作しますが、場合factory :users_accountステートメントでは、コードを追加します。

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

私は次のエラーを取得する:

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

にはどうすればいいの工場 \両側からそのアクセス関連したモデルにその問題を解決することができます(つまり、私のスペックファイルで、私はRoRの関連付けを使用したいですuser.accountおよびaccount.userのようなモデル方法

P .:私はFactory Girl and has_one質問を読みました。私のケースは、リンクされた質問で説明されたケースに非常に近いです。つまり、has_oneアソシエーション(UserUsers::Accountクラスの間)もあります。

+0

「User」を持っていて、「Users :: Account」を持っていれば、それは複数であるべきですか、それとも 'User :: Account'かtypoですか? – nowk

+0

@kwon - それはタイプミスではありません。私は 'Users :: Account'クラスを持っています。 – Backo

答えて

14

the docsによれば、アソシエーションの両側をファクトリに入れることはできません。アフターコールバックを使用して、返すオブジェクトを設定する必要があります。例えば

は、factories/users/account.rbファイルで、あなたはhas_manyのアソシエーションの

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

のようなものを入れて、あなたはそれらの* _listの機能を使用する必要があります。

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

注:私は、ドキュメントの例では、オブジェクトには何も割り当てない誤解を招くビットであると考えています。私はそれが何かのようにすべきだと信じています(割り当てに注意してください)。

# 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