如何避免在factory_girl中循环创建关联模型? [英] How to avoid circular creation of associated models in factory_girl?
问题描述
我有一个应用,用户可以在其中使用多种服务登录,例如Google Plus,Facebook,Twitter等.
I have an app where a user can sign in with multiple services, e.g. Google Plus, Facebook, Twitter, etc.
为方便起见,我有一个has_many
Identity
记录的基本User
模型.
To facilitate this, I have a base User
model which has_many
Identity
records.
- 每个
Identity
记录都有一个provider
字段(例如"Google"
,"Facebook"
等),以指示用于登录的提供商. - 有一个ActiveRecord验证,仅允许用户拥有每种类型的提供程序之一.因此,用户不能有2个
"Google"
identities
.
- Each
Identity
record has aprovider
field (e.g."Google"
,"Facebook"
, etc...) to indicate what provider is used to sign in. - There's an ActiveRecord validation that only lets a user have one of each type of provider. So a user can't have 2
"Google"
identities
.
我建立工厂的方式如下:
I set up my factories as follows:
FactoryGirl.define do
factory :user do
sequence(:name) { |n| "Julio Jones-#{n}"}
sequence(:email) { |n| "julio.jones-#{n}@atl.com" }
after(:create) do |user|
create(:identity, user: user)
end
end
factory :identity do
user
provider "Google"
email { user.email }
password "password"
end
end
User
模型具有创建Identity
记录的回调.运行时效果很好
The User
model has a callback that creates an Identity
record. It works great when running
user = FactoryGirl.create(:user)
但是,如果我改为创建identity
However, if I create the identity
instead
identity = FactoryGirl.create(:identity)
identity
工厂将首先尝试创建父级user
,该父级又将创建另一个identity
.当它最终回到创建调用的identity
时,已经存在另一个identity
,该identity
与该user
相同,并且失败了.
the identity
factory will first try to create a parent user
, which will in turn create another identity
. When it finally gets back to creating the identity
I made the call to, another identity
already exists with the same provider
for that user
and it fails.
本质上,我需要一种方法使after(:create)
回调在:identity
工厂正在创建user
时不触发.有没有办法告诉是什么原因导致了创建特定工厂的调用?
Essentially, I need a way for the after(:create)
callback to NOT trigger when the user
is being created by the :identity
factory. Is there a way to tell what made the call to create a particular factory?
推荐答案
我认为工厂没有一种很好的方式来告诉工厂,而无需合作即可被另一个工厂调用. (您始终可以检查caller_locations
,但这并不好.)相反,让一个工厂使用瞬态属性告诉另一工厂表现不同:
I don't think there's a nice way for a factory to tell that it's been called by another without collaboration. (You can always inspect caller_locations
, but that's not nice.) Instead, have one factory tell the other to behave differently using a transient attribute:
FactoryGirl.define do
factory :user do
transient do
create_identity true
end
after(:create) do |user, evaluator|
if evaluator.create_identity
create(:identity, user: user)
end
end
end
factory :identity do
association :user, factory: :user, create_identity: false
end
end
这篇关于如何避免在factory_girl中循环创建关联模型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!