Factory Girl 中的附属工厂

发布于 2024-11-07 15:23:51 字数 1534 浏览 1 评论 0原文

我有2个工厂。 Beta_user 和 Beta_invite。基本上,在 Beta_user 可以有效保存之前,我必须创建一个 Beta_invite 条目。不幸的是,这些模型没有明确的关联,但它们确实共享一个电子邮件字段。

Factory.sequence :email do |n|
  "email#{n}@factory.com"
end

#BetaInvite
Factory.define :beta_invite do |f|
  f.email {Factory.next(:email)}
  f.approved false
  f.source "web"
end

#User
Factory.define :user do |f|
  f.email {Factory.next(:email)}
  f.password "password"
end


#User => BetaUser
Factory.define :beta_user, :parent => :user do |f|
  f.after_build do |user|
    if BetaInvite.find_by_email(user.email).nil?
      Factory(:beta_invite, :email => user.email)
    end
  end
end

因此,在 beta beta_user 工厂中,我尝试使用 after_build 回调来创建 beta_invite 工厂。

然而它似乎是异步的或者什么的。可能进行 find_by_email 获取?

如果我尝试这样做:

Factory(:beta_user)
Factory(:beta_user)
Factory(:beta_user)

我收到一条失败消息,指出该用户的电子邮件没有 beta_invite 的记录。

相反,如果我尝试:

Factory.build(:beta_user).save
Factory.build(:beta_user).save
Factory.build(:beta_user).save

我会得到更好的结果。就好像调用 .build 方法并等待保存可以让 beta_invite 工厂有时间创建一样。而不是直接调用Factory.create。文档说,在调用 Factory.create 的情况下, after_build 和 after_create 回调都会被调用。

非常感谢任何帮助。

更新:

因此,我使用的用户模型会对检查是否有测试版邀请的方法进行 before_validation 调用。如果我将此方法调用移至 before_save 。它工作正常。有什么我忽略的事情吗? Factory_girl 何时运行与 active-record 的 before_validationbefore_save 相关的 after_buildafter_create 回调?

I have 2 factories. Beta_user and Beta_invite. Basically before a Beta_user can validly save I have to create an entry of Beta_invite. Unfortunately these models don't have clean associations, but they do share an email field.

Factory.sequence :email do |n|
  "email#{n}@factory.com"
end

#BetaInvite
Factory.define :beta_invite do |f|
  f.email {Factory.next(:email)}
  f.approved false
  f.source "web"
end

#User
Factory.define :user do |f|
  f.email {Factory.next(:email)}
  f.password "password"
end


#User => BetaUser
Factory.define :beta_user, :parent => :user do |f|
  f.after_build do |user|
    if BetaInvite.find_by_email(user.email).nil?
      Factory(:beta_invite, :email => user.email)
    end
  end
end

So in the beta beta_user factory I am trying to use the after_build call back to create the beta_invite factory.

However it seems to be acting async or something. Possibly doing the find_by_email fetch?

If I try this:

Factory(:beta_user)
Factory(:beta_user)
Factory(:beta_user)

I get a failure stating that there is no record of a beta_invite with that users email.

If instead I try:

Factory.build(:beta_user).save
Factory.build(:beta_user).save
Factory.build(:beta_user).save

I get better results. As if calling the .build method and waiting to save allows time for the beta_invite factory to be created. Instead of calling Factory.create directly. The docs say that in the case of calling Factory.create both the after_build and after_create callbacks get called.

Any help is much appreciated.

UPDATE:

So the User model I am using does a before_validation call to the method that checks if there is a beta invite. If I move this method call to before_save instead. It works correctly. Is there something i'm over looking. When does factory_girl run the after_build and after_create callbacks in relation to active-record's before_validation and before_save?

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

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

发布评论

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

评论(3

蓝色星空 2024-11-14 15:23:52

我发现 评论给出了一个非常好的例子:

term = create(:term)
period = create(:period, term: term)
candidate = create(:candidate, term: term)

我将其应用于我的情况并可以确认它是否有效。

I found this comment gave a really good example:

term = create(:term)
period = create(:period, term: term)
candidate = create(:candidate, term: term)

I applied it to my situation and can confirm it works.

前事休说 2024-11-14 15:23:51

对我来说,它似乎应该能够工作,但我在 Factory-girl 中的关联也遇到了问题。在这种情况下,如果关系不太明显,我喜欢使用的方法是在工厂内部定义一个特殊方法,如下所示:

def Factory.create_beta_user
  beta_invite = Factory(:beta_invite)
  beta_user = Factory(:user, :email => beta_invite.email)
  beta_user
end

并在测试中使用它,只需写

Factory.create_beta_user

希望这有帮助。

To me it seems like it just should be able to work, but I have had problems with associations in Factory-girl as well. An approach I like to use in a case like this, if the relations are less evident, is to define a special method, inside your factory as follows:

def Factory.create_beta_user
  beta_invite = Factory(:beta_invite)
  beta_user = Factory(:user, :email => beta_invite.email)
  beta_user
end

and to use that in your tests, just write

Factory.create_beta_user

Hope this helps.

高速公鹿 2024-11-14 15:23:51

不确定这是否对您有帮助,但这是我使用的代码:

# Create factories with Factory Girl

FactoryGirl.define do
  # Create a sequence of unique factory users
  sequence(:email) { |n| "factoryusername+#{n}@example.com"}

  factory :user do
    email
    password "factorypassword"

    # Add factory user email to beta invite
    after(:build) {|user| BetaInvite.create({:email => "#{user.email}"})}
  end 
end

Not sure if this would help you but this is the code I used:

# Create factories with Factory Girl

FactoryGirl.define do
  # Create a sequence of unique factory users
  sequence(:email) { |n| "factoryusername+#{n}@example.com"}

  factory :user do
    email
    password "factorypassword"

    # Add factory user email to beta invite
    after(:build) {|user| BetaInvite.create({:email => "#{user.email}"})}
  end 
end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文