ruby-on-rails – Factory Girl与现有对象创建关联

我是FactoryGirl的新手,我正在尝试以下简单的场景?
factory :female,:class => Gender do
  code 'Female'
end

factory :male,:class => Gender do
  code 'Male'
end

factory :papas,:class => Customer do
  first_name 'Jim'
  last_name 'Papas'
  association :gender,:factory => :male,:strategy => :build
end

factory :dumas,:class => Customer do
  first_name 'Mary'
  last_name 'Dumas'
  association :gender,:factory => :female,:strategy => :build
end

然后在我的测试中:

create(:male)
 create(:female)
 create(:papas)
 create(:dumas)

请注意,Customer类有一个关联“belongs_to”Gender类和一个验证规则,说明“gender_id”应该存在.我也有一个验证关于性别类的唯一性的代码.

在上面的“create((papas)”语句中,在我的测试中,我收到了将要创建的Customer无效的错误,因为“gender_id”为nil.

如果我删除了“:strategy =>:build”在Customer:Papas工厂协会与性别,那么我会收到一个错误,当尝试创建:papas,性别的代码已经存在.

我需要做什么,以便我的测试创建如上所述的数据?

请注意,我想在没有客户的情况下创建性别,在其他测试中.不要告诉我用工厂创建命令创建客户,让客户同时创建性别.如果我尝试创造两个相同性别的客户,这将不会奏效.

还有一个比一个更好的答案:

@male = create(:male)
@female = create(:female)
create(:papas,:gender => @male)
create(:dumas,:gender => @female)

(当使用灯具时,这些东西已经准备就绪,我要回到灯具吗?)

解决方法

您可以通过不使用工厂进行性别实例并在客户工厂中使用回调来实现所需的目标.

你并没有从性别工厂那里获得很多东西(尽管我感谢它可以简化为了提出这个问题).你可以很容易地做到这一点得到一个性别:

Gender.find_or_create_by_code!('Male')

然后在您的客户工厂,您可以使用以前的回调来设置“性别”:

factory :dumas,:class => Customer do
  first_name 'Mary'
  last_name 'Dumas'
  before_create do |customer|
    customer.gender = Gender.find_or_create_by_code!('Female')
  end
end

最近更改了在factory_girl中使用回调的格式,如果您使用3.3或更高版本,则需要执行以下操作:

before(:create) do |customer|

而不是before_create.

如果创建性别比您的示例更复杂,您仍然可以使用工厂创建性别,然后使用find_by_code与使用回调的客户联系起来. find_or_create_by_code!的insteand.

相关文章

以下代码导致我的问题: class Foo def initialize(n=0) @n = n end attr_accessor :n d...
这是我的spec文件,当为上下文添加测试“而不是可单独更新用户余额”时,我得到以下错误. require 's...
我有一个拦截器:DevelopmentMailInterceptor和一个启动拦截器的inititializer setup_mail.rb. 但我想将...
例如,如果我有YAML文件 en: questions: new: 'New Question' other: recent: ...
我听说在RSpec中避免它,let,let !,指定,之前和主题是最佳做法. 关于让,让!之前,如果不使用这些,我该如...
我在Rails中使用MongoDB和mongo_mapper gem,项目足够大.有什么办法可以将数据从Mongoid迁移到 Postgres...