工厂女孩将论点传递给多对多协会

factory girl pass argument to many to many association

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 中的参数位置?这是多对多关系。

table 房子:

:id, :name

table 会员:

:id, :name

table house_member:

:id, :house_id, :member_id, :position

不幸的是,在 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

您实际上是在创建重复的连接模型。如果你是一个很好的 boy/girl 并且在 house_idmember_id 上添加了一个唯一的复合索引,你会得到一个错误。

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

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

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

你需要加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

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

FactoryGirl.create_list(:house, 4, position: 44, members: FactoryGirl.create_list(:member, 3))
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

将参数传递给工厂:class as

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