工厂女孩将论证传递给多对多

时间:2017-10-26 10:25:08

标签: ruby-on-rails ruby factory-bot

FactoryGirl.define do
  factory :house do
    after(:create) do |house, evaluator|
      evaluator.members.each do |member|
        create(:house_member, house: house, member: member, position: 2)
      end 
    end
  end

FactoryGirl.create_list(:house, 4, members: FactoryGirl.create_list(:member, 3))

如何在FactoryGirl.create_list中传递参数位置?这是一对多关系。

桌子:

:id, :name

表成员:

:id, :name

table house_member:

:id, :house_id, :member_id, :position

3 个答案:

答案 0 :(得分:2)

您需要添加transient attributes之类的内容。

FactoryGirl.define do
  transient do
    position 2
    members []
  end

  factory :house do
    after(:create) do |house, evaluator|
      evaluator.members.each do |member|
        create(:house_member, house: house, member: member, position: evaluator.position)
      end 
    end
  end

现在您可以像position这样传递参数FactoryGirl.create_list

FactoryGirl.create_list(:house, 4, position: 44, members: FactoryGirl.create_list(:member, 3))

答案 1 :(得分:1)

不幸的是,在Rails中隐式创建连接记录时,无法传递属性。

假设:

class House < ApplicationRecord
  has_many :house_members
  has_many :members, through: house_members
end

class HouseMember < ApplicationRecord
  belongs_to :house
  belongs_to :member
end

class Member < ApplicationRecord
  has_many :house_members
  has_many :houses, through: :house_members
end

当我这样做时:

house = House.create(name: 'Fallingwater')
house.members.create(name: 'Max')

无法传递作为连接的HouseMember模型的属性。 相反,您需要显式创建连接模型:

house = House.create
house.house_members.create(member: Member.create(name: 'Max'), position: 2)

或者在事后改变记录:

house = House.create(name: 'Fallingwater')
member = house.members.create(name: 'Max')
house.house_members
     .where(member: member).first.update_attribute(position: 2)

这对您有何影响?

当你这样做时:

evaluator.members.each do |member|
  create(:house_member, house: house, member: member, position: 2)
end

您实际上是在创建重复的连接模型。如果你是一个好男孩/女孩,并在house_idmember_id添加了一个独特的复合索引,你会收到错误。

您可以做的是更改联接记录:

evaluator.house_members.each do |hm|
  hm.update_attribute(position: 2)
end

根据应用程序中实际存在的位置,您可能希望通过在DB中设置默认值来处理它。

答案 2 :(得分:0)

FactoryGirl.define do
 factory :class do
  trait :with_comments do
   transient do
     email {nil}
     address {nil}
     id {nil}
   end

   after(:create) do |class, evaluator|
     class.students << FactoryGirl.create(:students, :id => evaluator.id, :email => evaluator.email, :address => evaluator.address )
   end
 end
end

将参数传递给factory:class为

@class = create(:class, :with_comments, id: 1, email: 'abc@gmail.com', address: 'House No. XYZ')