在 Rails 6 和 FactoryGirl 4.9 中,如何将原始对象与正在创建的 has_many 关系联系起来?
In Rails 6 and FactoryGirl 4.9, how do I tie the original object back its has_many relation that's being created?
我正在使用 Rails 6 和 FactoryGirl 4.9.0。我有这些模型,一个有一个 has_many 和另一个 …
class Contract < ApplicationRecord
…
belongs_to :client
class Client < ApplicationRecord
…
has_many :contracts
在我的工厂里,我有
FactoryGirl.define do
factory :client do
name "Test Client”
end
factory :dp_client, class: Client do
Contracts { [create(:contract)] }
end
end
但是当我去使用工厂的时候,
create(:dp_client)
我收到错误消息……
Validation failed: Client must exist
在我的工厂中创建“has_many”关系时,我是否将它与创建它的对象联系起来?
是这样完成的:
FactoryBot.define do
factory :client do
name { "Test client" }
end
factory :contract do
association :client
end
factory :dp_client, class: Client do
name { "Test DP Client"}
contracts { [ FactoryBot.create(:contract) ]}
end
end
FactoryBot.define do
factory :client do
name { "Test client" }
end
factory :contract do
client
end
factory :dp_client, class: Client do
name { "client name" }
after(:create) do |client|
create(:contract, client: client)
end
end
end
有多种方法可以解决这个问题。
选项 1:
使用您所在街区的实例。 FactoryBot 已将 self
设置为工厂,并将其作为参数传入。所以这两个都应该有效:
contracts { |factory| [build(:contract, client: factory.instance)] }
# or
contracts { [build(:contract, client: instance)] } # because self is the factory
注意:我在这里使用 build
而不是 create
因为 Rails 如何自动保存关联。在大多数用例中,两者都应该可以正常工作。
选项 2:使用 after_create
这是Saiqul Haq提出的解决方案。主要缺点:它只适用于 create
(不适用于 build
)。另外值得注意的是:它可能无法反映您的应用程序的真实情况(例如,如果您的记录总是一起创建的)。
选项 3:使用 before_create
与之前的解决方案类似,但在工作流程方面可能更现实:
before(:create) do |client|
client.build_contract(attributes_for(:contract))
end
我正在使用 Rails 6 和 FactoryGirl 4.9.0。我有这些模型,一个有一个 has_many 和另一个 …
class Contract < ApplicationRecord
…
belongs_to :client
class Client < ApplicationRecord
…
has_many :contracts
在我的工厂里,我有
FactoryGirl.define do
factory :client do
name "Test Client”
end
factory :dp_client, class: Client do
Contracts { [create(:contract)] }
end
end
但是当我去使用工厂的时候,
create(:dp_client)
我收到错误消息……
Validation failed: Client must exist
在我的工厂中创建“has_many”关系时,我是否将它与创建它的对象联系起来?
是这样完成的:
FactoryBot.define do
factory :client do
name { "Test client" }
end
factory :contract do
association :client
end
factory :dp_client, class: Client do
name { "Test DP Client"}
contracts { [ FactoryBot.create(:contract) ]}
end
end
FactoryBot.define do
factory :client do
name { "Test client" }
end
factory :contract do
client
end
factory :dp_client, class: Client do
name { "client name" }
after(:create) do |client|
create(:contract, client: client)
end
end
end
有多种方法可以解决这个问题。
选项 1:
使用您所在街区的实例。 FactoryBot 已将 self
设置为工厂,并将其作为参数传入。所以这两个都应该有效:
contracts { |factory| [build(:contract, client: factory.instance)] }
# or
contracts { [build(:contract, client: instance)] } # because self is the factory
注意:我在这里使用 build
而不是 create
因为 Rails 如何自动保存关联。在大多数用例中,两者都应该可以正常工作。
选项 2:使用 after_create
这是Saiqul Haq提出的解决方案。主要缺点:它只适用于 create
(不适用于 build
)。另外值得注意的是:它可能无法反映您的应用程序的真实情况(例如,如果您的记录总是一起创建的)。
选项 3:使用 before_create
与之前的解决方案类似,但在工作流程方面可能更现实:
before(:create) do |client|
client.build_contract(attributes_for(:contract))
end