【发布时间】:2014-01-21 22:05:46
【问题描述】:
我目前正在做一个项目,我想使用 factory girl 创建测试,但我无法使其与多态 has_many 关联一起工作。我已经尝试了其他文章中提到的许多不同的可能性,但它仍然不起作用。我的模型如下所示:
class Restaurant < ActiveRecord::Base
has_one :address, as: :addressable, dependent: :destroy
has_many :contacts, as: :contactable, dependent: :destroy
accepts_nested_attributes_for :contacts, allow_destroy: true
accepts_nested_attributes_for :address, allow_destroy: true
validates :name, presence: true
#validates :address, presence: true
#validates :contacts, presence: true
end
class Address < ActiveRecord::Base
belongs_to :addressable, polymorphic: true
# other unimportant validations, address is created valid, the problem is not here
end
class Contact < ActiveRecord::Base
belongs_to :contactable, polymorphic: true
# validations ommitted, contacts are created valid
end
所以基本上我想为带有地址和联系人的餐厅创建工厂(通过餐厅的存在验证,但如果不可能,即使没有它们)但我无法这样做。最终的语法应该是这样的:
let(:restaurant) { FactoryGirl.create(:restaurant) }
这也应该创建关联的地址和联系人。我读过很多文章,但我总是遇到某种错误。目前我的工厂(序列定义正确)是这样的:
factory :restaurant do
name
# address {FactoryGirl.create(:address, addressable: aaa)}
# contacts {FactoryGirl.create_list(:contact,4, contactable: aaa)}
# Validations are off, so this callback is possible
after(:create) do |rest|
# Rest has ID here
rest.address = create(:restaurant_address, addressable: rest)
rest.contacts = create_list(:contact,4, contactable: rest)
end
end
factory :restaurant_address, class: Address do
# other attributes filled from sequences...
association :addressable, factory: :restaurant
# addressable factory: restaurant
# association(:restaurant)
end
factory :contact do
contact_type
value
association :contactable, :factory => :restaurant
end
有没有一种方法可以在测试中设置一个命令并设置地址和联系人来创建餐厅?由于 after(:create) 回调,我真的需要摆脱我的验证吗? 当前状态如下:
- 餐厅是使用名称和 ID 创建的。
- 地址正在被创建 - 一切都是正确的,它具有所有值,包括 addressable_id 和 addressable_type
- 在创建所有联系人之后,一切正常,cntacts 具有正确的值。
- 此后,餐厅没有来自关联对象的任何 ID,也没有与地址或联系人的关联
- 之后,由于某种原因,重新构建了餐厅(可能是添加这些关联?)但它失败了:我得到 ActiveRecord:RecordInvalid。
我正在使用 factory_girl_rails 4.3.0、ruby 1.9.3 和 rails 4.0.1。我会很高兴得到任何帮助。
更新 1:
只是为了澄清我的目标,我希望能够使用一个命令在我的规范中创建餐厅,并能够访问应在创建餐厅时创建的关联地址和联系人。让我们忽略所有验证(我从一开始就在我的示例中将它们注释掉了)。当我使用 after(:build) 时,会创建第一家餐厅,然后使用餐厅 ID 为 addressable_id 和类名称为 addressable_type 创建地址。联系人也是如此,一切都是正确的。问题是,那家餐厅不知道它们(它没有地址或联系人的 ID),我无法从我想要的餐厅访问它们。
【问题讨论】:
标签: ruby-on-rails rspec factory-bot