2011-09-20 29 views
7

Tôi đang sử dụng Ruby on Rails 3.0.9, RSpec-rails 2 và FactoryGirl. Tôi đang cố gắng nêu ra một mô hình hiệp hội Nhà máy nhưng tôi đang gặp rắc rối.Vấn đề mô hình liên kết FactoryGirl: "SystemStackError: mức xếp chồng quá sâu"

Tôi có một tập tin factories/user.rb như sau:

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

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

và một tập tin factories/users/account.rb như sau:

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

Ví dụ trên làm việc như mong đợi trong file spec của tôi, nhưng nếu trong tuyên bố factory :users_account Tôi thêm mã association :user để có

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

tôi nhận được lỗi sau:

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

Làm thế nào tôi có thể giải quyết vấn đề đó như vậy để truy cập liên quan đến mô hình từ cả hai phía \ nhà máy (có nghĩa là, trong các tập tin spec của tôi Tôi muốn sử dụng liên kết ROR phương pháp mô hình như user.accountaccount.user) ?

P .: Tôi đọc câu hỏi Factory Girl and has_one và trường hợp của tôi rất gần với trường hợp được giải thích trong câu hỏi được liên kết. Nghĩa là, tôi cũng có một liên kết has_one (giữa các lớp UserUsers::Account).

+0

Chỉ cần tò mò, bạn có 'Người dùng' và sau đó bạn có Tài khoản người dùng', có nghĩa là số nhiều hoặc phải là 'Người dùng :: Tài khoản' hoặc lỗi đánh máy? – nowk

+0

@kwon - Nó không phải là lỗi đánh máy. Tôi có một lớp 'Users :: Account'. – Backo

Trả lời

14

Theo the docs, bạn không thể chỉ đặt cả hai mặt của các hiệp hội vào các nhà máy. Bạn sẽ cần phải sử dụng của họ sau khi gọi lại để thiết lập một đối tượng (s) để trở về.

Ví dụ, trong file factories/users/account.rb, bạn đặt một cái gì đó giống như

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

Đối với các hiệp hội has_many, bạn sẽ cần phải sử dụng chức năng _list * họ.

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

Lưu ý: Tôi tin rằng ví dụ trong tài liệu là một chút sai lệch nó không gán bất cứ điều gì để đối tượng. Tôi tin rằng nó phải là một cái gì đó như (lưu ý chuyển nhượng).

# 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 
Các vấn đề liên quan