简体   繁体   English

FactoryGirl关联模型故障:“SystemStackError:堆栈级别太深”

[英]FactoryGirl association model trouble: “SystemStackError: stack level too deep”

I am using Ruby on Rails 3.0.9, RSpec-rails 2 and FactoryGirl. 我正在使用Ruby on Rails 3.0.9,RSpec-rails 2和FactoryGirl。 I am trying to state a Factory association model but I am in trouble. 我试图陈述一个工厂协会模型,但我遇到了麻烦。

I have a factories/user.rb file like the following: 我有一个factories/user.rb文件,如下所示:

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

    association :account, :factory => :users_account, :method => :build, :email => 'foo@bar.com'
  end
end

and a factories/users/account.rb file like the following: 和一个factories/users/account.rb文件如下:

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

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 上面的示例在我的spec文件中按预期工作,但如果factory :users_account语句我添加了association :user代码以便有

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

I get the following error: 我收到以下错误:

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

How can I solve that problem so to access associated models from both sides\\factories (that is, in my spec files I would like to use RoR association model methods like user.account and account.user ) ? 如何解决这个问题,以便从双方\\工厂访问相关模型 (也就是说,在我的spec文件中,我想使用像user.accountaccount.user这样的RoR关联模型方法)

PS: I read the Factory Girl and has_one question and my case is very close to the case explained in the linked question. PS:我读过“ 工厂女孩”并且有一个问题,我的案子与链接问题中解释的情况非常接近。 That is, I have an has_one association too (between User and Users::Account classes). 也就是说,我也有一个has_one关联(在UserUsers::Account类之间)。

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. 您需要使用它们的after回调来设置要返回的对象。

For instance, in the factories/users/account.rb file, you put something like 例如,在factories/users/account.rb文件中,你可以输入类似的内容

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

For has_many associations, you'll need to use their *_list functions. 对于has_many关联,您需要使用他们的* _list函数。

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

Spyle's excellent answer (still working with Rails 5.2 and RSpec 3.8) will work for most associations. Spyle的优秀答案(仍然使用Rails 5.2和RSpec 3.8)将适用于大多数协会。 I had a use case where a factory needed to use 2 different factories (or different traits) for a single has_many association (ie. for a scope type method). 我有一个用例,工厂需要使用2个不同的工厂(或不同的特征)进行单个has_many关联(即用于范围类型方法)。

What I ended up coming up with was: 我最终提出的是:

# To build user with posts of category == 'Special' and category == 'Regular'
after(:create) do |user, evaluator|
  array = []
  array.push(FactoryBot.create_list(:post, 1, category: 'Regular')
  array.push(FactoryBot.create_list(:post, 1, category: 'Special')
  user.posts = array.flatten
end

This allowed the user to have 1 post of category 'Regular' and 1 post of category 'Special.' 这允许用户拥有1个“常规”类别的帖子和1个“特殊”类别的帖子。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM