Factory Girl:如何将一条记录关联到另一条记录而不创建新记录?

发布于 2024-09-29 00:49:06 字数 2150 浏览 1 评论 0原文

我正在使用 Factory Girl/Rspec2/Rails 3。

factories.rb 中,我有:

Factory.define :user do |user|
  user.name       'Some guy'
  user.email      '[email protected]'
  user.password   'password'
end

Factory.define :org_admin, :parent => :user do |user|
  user.email '[email protected]'
end

Factory.define :user_with_membership_request, :parent => :user do |user|
  user.email '[email protected]'
end

Factory.define :organization do |org|
  org.name        'MEC'
  org.description 'Mountain Equipment Co-op'
end

Factory.define :membership do |membership|
  membership.user { Factory(:user) }
  membership.organization { Factory(:organization) }
end

Factory.define :admin_membership, :parent => :membership do |membership|
  membership.user { Factory(:org_admin) }
  membership.is_admin true
  membership.status 'active'
end

Factory.define :membership_request, :parent => :membership do |membership|
  membership.user { Factory(:user_with_membership_request) }
  membership.status 'requested'
end

然后在我的 rspec 测试中我有:

  it 'should accept the membership request' do
    @org_admin = Factory(:org_admin)
    test_sign_in(@org_admin)
    @organization = Factory(:organization)
    @membership_request = Factory(:membership_request)

    put :update, :organization_id => @organization.id, :id => @membership_request.id, :acceptance => 'approve'
    ...
  end

当我运行测试时,我得到:

 Failure/Error: @membership_request = Factory(:membership_request)
 Validation failed: Name has already been taken

我明白原因失败是因为 FactoryGirl 正在创建另一个组织(同名)。

但我想做的是创建多个与同一组织关联的会员资格。我该怎么做?

谢谢。

肖恩

I'm using Factory Girl/Rspec2/Rails 3.

In factories.rb, I have:

Factory.define :user do |user|
  user.name       'Some guy'
  user.email      '[email protected]'
  user.password   'password'
end

Factory.define :org_admin, :parent => :user do |user|
  user.email '[email protected]'
end

Factory.define :user_with_membership_request, :parent => :user do |user|
  user.email '[email protected]'
end

Factory.define :organization do |org|
  org.name        'MEC'
  org.description 'Mountain Equipment Co-op'
end

Factory.define :membership do |membership|
  membership.user { Factory(:user) }
  membership.organization { Factory(:organization) }
end

Factory.define :admin_membership, :parent => :membership do |membership|
  membership.user { Factory(:org_admin) }
  membership.is_admin true
  membership.status 'active'
end

Factory.define :membership_request, :parent => :membership do |membership|
  membership.user { Factory(:user_with_membership_request) }
  membership.status 'requested'
end

and then in my rspec test I have:

  it 'should accept the membership request' do
    @org_admin = Factory(:org_admin)
    test_sign_in(@org_admin)
    @organization = Factory(:organization)
    @membership_request = Factory(:membership_request)

    put :update, :organization_id => @organization.id, :id => @membership_request.id, :acceptance => 'approve'
    ...
  end

When I run the test, I get:

 Failure/Error: @membership_request = Factory(:membership_request)
 Validation failed: Name has already been taken

I understand the reason for the failure is because FactoryGirl is creating another organization (with the same name).

But what I'd like to do is create several memberships all associated with the same organization. How do I do that?

Thanks.

Sean

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

忆依然 2024-10-06 00:49:06

您可以检查现有组织并使用它,如果不存在则创建一个:

Factory.define :membership do |membership|
  membership.user { Factory(:user) }
  membership.organization { Organization.first || Factory(:organization) }
end

FactoryGirl 4+ 更新:

Factory.define do
  factory :membership do
    user { create(:user) }
    organization { Organization.first || create(:organization) }
  end
end

另一种方法是为要重用的每个工厂使用唯一标识符(例如:名称),然后使用 initialize_with 来生成它:

factory :organization_1 do
  ignore { organization_name 'Sample Organization 1' }
  name { organization_name }
  initialize_with { Organization.find_or_create_by_name(organization_name) }
end

现在对 :organization_1 的任何引用都将始终检索相同的 Organization。显然,您必须使用不同的名称才能使其工作。

You could check for an existing organization and use it, or create one if none exists:

Factory.define :membership do |membership|
  membership.user { Factory(:user) }
  membership.organization { Organization.first || Factory(:organization) }
end

FactoryGirl 4+ update:

Factory.define do
  factory :membership do
    user { create(:user) }
    organization { Organization.first || create(:organization) }
  end
end

Another approach is to use unique identifiers (e.g.: names) for each factory that you want to reuse, then use initialize_with to generate it:

factory :organization_1 do
  ignore { organization_name 'Sample Organization 1' }
  name { organization_name }
  initialize_with { Organization.find_or_create_by_name(organization_name) }
end

Now any reference to :organization_1 will always retrieve the same Organization. Obviously, you must use distinct names for this to work.

强者自强 2024-10-06 00:49:06

有两件事。
1. 您可能仍然想为 Factory(:organization) 创建唯一的名称,您可以使用 Factory.sequence 来实现,这将为您生成唯一的名称。
2. 您可以传入 Factory(:membership_request, :organization => @organization) 来使用现有对象,而不是创建新对象。

There are two things.
1. You might still want to create unique names for Factory(:organisation) you can achieve that using Factory.sequence which will generate it uniquely for you.
2. You can pass in a Factory(:membership_request, :organization => @organization) to use the existing object instead of creating a new one.

述情 2024-10-06 00:49:06

使用 mongoid,您可以将 #find_or_create_by 方法与 Factory.attributes_for 结合使用,并执行类似的操作,

factory :membership do
    organization { Organization.find_or_create_by(Factory.attributes_for(:organization))}
end

我确信 ActiveRecord 也有类似的操作。

With mongoid you can take combine the use of the #find_or_create_by method with Factory.attributes_for and do something like this

factory :membership do
    organization { Organization.find_or_create_by(Factory.attributes_for(:organization))}
end

I'm sure ActiveRecord has something similar.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文