我的模型contact
has_many :locations, through: :relationships
以及has_many :teams, through: :contacts_teams
。
联系人必须拥有关联的team
和location
才能通过验证。换句话说:新的contact
必须具有关联的relationship
记录和关联的contacts_team
记录。以下是模型:
#models/contact.rb
class Contact < ActiveRecord::Base
has_many :contacts_teams
has_many :teams, through: :contacts
has_many :relationships, dependent: :destroy
has_many :locations, through: :relationships
accepts_nested_attributes_for :contacts_teams, allow_destroy: true
# upon create, validate that at least one associated team and one associated location exist
validate :at_least_one_contacts_team
validate :at_least_one_relationship
private
def at_least_one_contacts_team
return errors.add :base, "Must have at least one Team" unless contacts_teams.length > 0
end
def at_least_one_relationship
return errors.add :base, "Must have at least one Location" unless relationships.length > 0
end
end
#models/contacts_team.rb
class ContactsTeam < ActiveRecord::Base
belongs_to :contact
belongs_to :team
end
#models/team.rb
class Team < ActiveRecord::Base
has_many :contacts_teams
has_many :contacts, through: :contacts_teams
end
#models/relationship.rb
class Relationship < ActiveRecord::Base
belongs_to :contact
belongs_to :location
end
#models/location.rb
class Location < ActiveRecord::Base
has_many :relationships
has_many :contacts, through: :relationships
end
进行测试:使用factory_girl我想创建一个能够成功创建contact
记录的contact
工厂。由于每个contact
记录都需要关联的contacts_team
记录和relationship
记录:当我创建contact
记录时,也应创建这些记录。同样:contacts_team
记录应与其关联的现有team
,并且relation
记录应与其关联的现有location
。所以基本上它应该创建location
和team
记录。
如何创建与工厂的联系人记录,这实际上会创建关联的contacts_team
记录和relationship
记录?
以下是我目前的工厂:
FactoryGirl.define do
factory :contact do
first_name "Homer"
last_name "Simpson"
title "Nuclear Saftey Inspector"
end
end
FactoryGirl.define do
factory :contacts_team do
end
end
FactoryGirl.define do
factory :team do
name "Safety Inspection Team"
end
end
FactoryGirl.define do
factory :relationship do
end
end
FactoryGirl.define do
factory :location do
name "Safety Location"
end
end
如果使用factory_girl很难/不可能这样做:我怎么能用直接的rspec做到这一点?问题在于我无法创建contacts_team
条记录或relationship
条记录,因为它与之关联的contact
尚未存在!我无法创建contact
记录,因为相关的contacts_team
记录或relationship
记录尚未存在。好像我被困了,但必须有办法做到这一点并不是马虎。
答案 0 :(得分:1)
我上周才有类似的要求。
在工厂结束时,您可以致电下一家工厂,然后他们就会相关联。例如:
/spec/factories/contacts.rb
FactoryGirl.define do
factory :contact do |c|
first_name "Homer"
last_name "Simpson"
title "Nuclear Saftey Inspector"
# now, call the other two factories
relationship
contacts_team
end
factory :contacts_team do
# call the team factory
team
end
factory :relationship do
# call the location factory
location
end
# define the team and location factories...
end
现在,在/spec/controllers/contacts_controller_spec.rb
中contact = FactoryGirl.create(:contact)
您可以使用工厂女孩来创建联系人,即使您只需要一个位置,因为所有内容都会立即生成。
替代(rspec)
不要&#34;链&#34;你的工厂,而不是/spec/controllers/contacts_controller_spec.rb
contact = FactoryGirl.create(:contact)
# use .create_list(model, number, parent) to make children of a specific parent
contacts_team = FactoryGirl.create_list(:contacts_team, 3, :contact => contact)
relationship = FactoryGirl.create_list(:relationship, 3, :contact => contact)
team = FactoryGirl.create_list(:team, 3, :contacts_team => contacts_team)
location = FactoryGirl.create_list(:location, 3, :relationship => relationship)
这将创建一个联系人,包含3个contact_teams(包含3个团队),以及3个关系(包含3个位置)
希望这有助于您找出制作测试数据的正确模式:)
答案 1 :(得分:1)
这是答案。我们需要构建关联的记录(contacts_team
记录和relationship
记录),然后我们将所有记录保存在同一时间到数据库(就像rails保存嵌套属性的方式):
#factories/contact.rb
FactoryGirl.define do
factory :contact do
first_name "Homer"
last_name "Simpson"
title "Nuclear Saftey Inspector"
agency
contacts_teams {build_list :contacts_team, 1 }
relationships {build_list :relationship, 1 }
end
end
#factories/contacts_teams.rb
FactoryGirl.define do
factory :contacts_team do
team
end
end
#factories/teams.rb
FactoryGirl.define do
factory :team do
name "Safety Inspection Team"
end
end
#factories/relationships.rb
FactoryGirl.define do
factory :relationship do
location
end
end
#factories/locations.rb
FactoryGirl.define do
factory :location do
name "Safety Location"
end
end
然后您需要做的就是:
create(:contact)
然后,它会立即创建contact
记录,team
记录,location
记录,关联的contacts_team
记录以及相关的{{1}记录。
答案 2 :(得分:0)
基本上,你可以采取多种方式。但通常建议的一种方法是使用FactoryGirl after(:create)
或after(:build)
。在您的情况下,如果您的所有型号都有工厂,您可以轻松致电:
after(:create) do |team, evaluator|
create_list(:contact_team, 5, team: team)
end
根据文档,在(:create)之后产生团队和评估者,它们存储工厂的所有值,包括瞬态属性
这将为您创建5个与团队关联的contact_teams。对于每个工厂,如果您定义这样的所有关系,您将定义完整的关联。另一种方法是遵循诺姆的建议,这也是好的,但有其自身的局限性。 您可以在此处找到更多信息:FactoryGirl Associations