【问题标题】:How can I build/create a many-to-many association in factory_girl?如何在 factory_girl 中建立/创建多对多关联?
【发布时间】:2010-07-30 22:47:36
【问题描述】:

我有一个 Person 模型,它与 Email 模型具有多对多关系,我想创建一个工厂,让我为这个人生成名字和姓氏(这已经完成)并根据该人的姓名创建一个电子邮件地址。这是我创建person 的名称:

Factory.sequence :first_name do |n|
  first_name = %w[FirstName1 FirstName2] # ... etc (I'm using a real subset of first names)
  first_name[(rand * first_name.length)]
end

Factory.sequence :last_name do |n|
  last_name = %w[LastName1 LastName2] # ... etc (I'm using a real subset of last names)
  last_name[(rand * last_name.length)]
end

Factory.define :person do |p|
  #p.id ???
  p.first_name { Factory.next(:first_name) }
  p.last_name { Factory.next(:last_name) }
  #ok here is where I'm stuck
  #p.email_addresses {|p| Factory(:email_address_person_link) }
end

Factory.define :email_address_person_link do |eapl|
  # how can I link this with :person and :email_address ? 
  # eapl.person_id ???
  # eapl.email_address_id ???
end

Factory.define :email_address do |e|
  #how can I pass p.first_name and p.last_name into here?
  #e.id ???
  e.email first_name + "." + last_name + "@test.com"
end

【问题讨论】:

    标签: ruby-on-rails many-to-many rspec factory-bot


    【解决方案1】:

    好的,我想我明白你现在在问什么了。像这样的东西应该可以工作(未经测试,但我在另一个项目中做过类似的事情):

    Factory.define :person do |f|
      f.first_name 'John'
      f.last_name 'Doe'
    end
    
    Factory.define :email do |f|
    end
    
    # This is optional for isolating association testing; if you want this 
    # everywhere, add the +after_build+ block to the :person factory definition
    Factory.define :person_with_email, :parent => :person do |f|
      f.after_build do |p|
        p.emails << Factory(:email, :email => "#{p.first_name}.#{p.last_name}@gmail.com")
        # OR
        # Factory(:email, :person => p, :email => "#{p.first_name}.#{p.last_name}@gmail.com")
      end
    end
    

    如上所述,使用第三个独立工厂是可选的。在我的例子中,我并不总是想为每个测试生成关联,所以我创建了一个单独的工厂,我只在一些特定的测试中使用它。

    【讨论】:

    【解决方案2】:

    使用回调(有关更多信息,请参阅 FG 文档)。回调会通过当前正在构建的模型。

    Factory.define :person do |p|
      p.first_name { Factory.next(:first_name) }
      p.last_name { Factory.next(:last_name) }
      p.after_build { |m| p.email_addresses << "#{m.first_name}.#{m.last_name}@test.com" }
    end
    

    我认为这行得通。

    您还可以通过使用 Faker gem 为您创建真实的姓名和电子邮件地址来节省一些工作。

    【讨论】:

    • 我不认为这正是我想要的。为了清楚起见,我编辑了我的问题。为伪造的宝石+1。不过,我想弄清楚如何做到这一点,以便更好地了解 factory_girl 的工作原理。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-10
    相关资源
    最近更新 更多