问题描述
我使用的是 Ruby on Rails 3.0.9、RSpec-rails 2 和 FactoryGirl.我正在尝试声明工厂关联模型,但我遇到了麻烦.
I am using Ruby on Rails 3.0.9, RSpec-rails 2 and FactoryGirl. I am trying to state a Factory association model but I am in trouble.
我有一个 factories/user.rb
文件,如下所示:
I have a factories/user.rb
file like the following:
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
文件,如下所示:
and a factories/users/account.rb
file like the following:
FactoryGirl.define do
factory :users_account, :class => Users::Account do
sequence(:email) {|n| "foo#{n}@bar.com" }
...
end
end
上面的示例在我的规范文件中按预期工作,但是 if 在 factory :users_account
语句中我添加了 association :user
代码所以有
The above example works as expected in my spec files, but if in the factory :users_account
statement I add the association :user
code so to have
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
我如何解决这个问题,以便从双方工厂访问关联模型(也就是说,在我的规范文件中,我想使用像 user.account 这样的 RoR 关联模型方法
和 account.user
)?
How can I solve that problem so to access associated models from both sidesfactories (that is, in my spec files I would like to use RoR association model methods like user.account
and account.user
)?
PS:我阅读了Factory Girl and has_one 问题,我的情况非常接近链接问题中解释的案例.也就是说,我也有一个 has_one
关联(在 User
和 Users::Account
类之间).
P.S.: I read the Factory Girl and has_one question and my case is very close to the case explained in the linked question. That is, I have an has_one
association too (between User
and Users::Account
classes).
推荐答案
根据文档,不能随便把双方的协会都放进工厂.您需要使用它们的 after 回调来设置要返回的对象.
According to the docs, you can't just put both sides of the associations into the factories. You'll need to use their after callback to set an object(s) to return.
例如,在 factories/users/account.rb
文件中,您输入类似
For instance, in the factories/users/account.rb
file, you put something like
after(:build) do |user_account, evaluator|
user_account.user = FactoryGirl.build(:user, :account=>user_account)
end
对于 has_many 关联,您需要使用它们的 *_list 函数.
For has_many associations, you'll need to use their *_list functions.
after(:build) do |user_account, evaluator|
user_account.users = FactoryGirl.build_list(:user, 5, :account=>user_account)
end
注意:我认为文档中的示例有点误导,它没有为对象分配任何内容.我相信它应该是这样的(注意作业).
Note: I believe the example in the docs is a bit misleading it doesn't assign anything to the object. I believe it should be something like (note the assignment).
# 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
这篇关于FactoryGirl 关联模型故障:“SystemStackError: stack level too deep"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!