How to define factories that are dependent on each other without Trait not registered or Factory not registered?

1,746 views
Skip to first unread message

Gary Weaver

unread,
Nov 5, 2012, 1:14:36 PM11/5/12
to factor...@googlegroups.com
Using:

    ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-darwin11.4.0]
    rails (= 3.2.8)
    factory_girl (4.1.0)
    factory_girl_rails (4.1.0)

When I have something similar to the following factories defined in factories.rb (but with more attributes, etc.):

  factory :foo do
    bar
  end
 
  factory :bar do
    trait :with_foos do; FactoryGirl.create_list :foo, 2; end
  end

I get this when I run rspec:

/path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/registry.rb:24:in `find': Trait not registered: bar (ArgumentError)
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/decorator.rb:10:in `method_missing'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl.rb:93:in `trait_by_name'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/definition.rb:98:in `trait_by_name'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/definition.rb:90:in `block in base_traits'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/definition.rb:90:in `map'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/definition.rb:90:in `base_traits'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/definition.rb:50:in `block in compile'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/definition.rb:49:in `each'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/definition.rb:49:in `compile'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/factory.rb:86:in `compile'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/factory_runner.rb:14:in `run'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/strategy_syntax_method_registrar.rb:19:in `block in define_singular_strategy_method'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/strategy_syntax_method_registrar.rb:27:in `block (2 levels) in define_list_strategy_method'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/strategy_syntax_method_registrar.rb:27:in `times'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/strategy_syntax_method_registrar.rb:27:in `each'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/strategy_syntax_method_registrar.rb:27:in `map'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/strategy_syntax_method_registrar.rb:27:in `block in define_list_strategy_method'
    from /path/to/git/my_project/spec/support/factories.rb:17:in `block (3 levels) in <top (required)>'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/trait.rb:12:in `instance_eval'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/trait.rb:12:in `initialize'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/definition_proxy.rb:154:in `new'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/definition_proxy.rb:154:in `trait'
    from /path/to/git/my_project/spec/support/factories.rb:17:in `block (2 levels) in <top (required)>'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/syntax/default.rb:18:in `instance_eval'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/syntax/default.rb:18:in `factory'
    from /path/to/git/my_project/spec/support/factories.rb:15:in `block in <top (required)>'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/syntax/default.rb:49:in `instance_eval'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/syntax/default.rb:49:in `run'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/syntax/default.rb:7:in `define'
    from /path/to/git/my_project/spec/support/factories.rb:3:in `<top (required)>'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/activesupport-3.2.8/lib/active_support/dependencies.rb:251:in `require'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/activesupport-3.2.8/lib/active_support/dependencies.rb:251:in `block in require'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/activesupport-3.2.8/lib/active_support/dependencies.rb:236:in `load_dependency'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/activesupport-3.2.8/lib/active_support/dependencies.rb:251:in `require'
    from /path/to/git/my_project/spec/spec_helper.rb:12:in `block in <top (required)>'
    from /path/to/git/my_project/spec/spec_helper.rb:12:in `each'
    from /path/to/git/my_project/spec/spec_helper.rb:12:in `<top (required)>'
    from /path/to/git/my_project/spec/controllers/service/competencies_controller_spec.rb:1:in `require'
    from /path/to/git/my_project/spec/controllers/service/competencies_controller_spec.rb:1:in `<top (required)>'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/rspec-core-2.11.1/lib/rspec/core/configuration.rb:780:in `load'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/rspec-core-2.11.1/lib/rspec/core/configuration.rb:780:in `block in load_spec_files'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/rspec-core-2.11.1/lib/rspec/core/configuration.rb:780:in `map'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/rspec-core-2.11.1/lib/rspec/core/configuration.rb:780:in `load_spec_files'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/rspec-core-2.11.1/lib/rspec/core/command_line.rb:22:in `run'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/rspec-core-2.11.1/lib/rspec/core/runner.rb:69:in `run'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/rspec-core-2.11.1/lib/rspec/core/runner.rb:8:in `block in autorun'

Which I switch the order around:

  factory :bar do
    trait :with_foos do; FactoryGirl.create_list :foo, 2; end
  end

  factory :foo do
    bar
  end

I get this when I run rspec:

/path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/registry.rb:24:in `find': Factory not registered: foo (ArgumentError)
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/decorator.rb:10:in `method_missing'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl.rb:71:in `factory_by_name'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/factory_runner.rb:12:in `run'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/strategy_syntax_method_registrar.rb:19:in `block in define_singular_strategy_method'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/strategy_syntax_method_registrar.rb:27:in `block (2 levels) in define_list_strategy_method'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/strategy_syntax_method_registrar.rb:27:in `times'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/strategy_syntax_method_registrar.rb:27:in `each'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/strategy_syntax_method_registrar.rb:27:in `map'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/strategy_syntax_method_registrar.rb:27:in `block in define_list_strategy_method'
    from /path/to/git/my_project/spec/support/factories.rb:10:in `block (3 levels) in <top (required)>'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/trait.rb:12:in `instance_eval'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/trait.rb:12:in `initialize'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/definition_proxy.rb:154:in `new'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/definition_proxy.rb:154:in `trait'
    from /path/to/git/my_project/spec/support/factories.rb:10:in `block (2 levels) in <top (required)>'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/syntax/default.rb:18:in `instance_eval'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/syntax/default.rb:18:in `factory'
    from /path/to/git/my_project/spec/support/factories.rb:8:in `block in <top (required)>'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/syntax/default.rb:49:in `instance_eval'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/syntax/default.rb:49:in `run'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/factory_girl-4.1.0/lib/factory_girl/syntax/default.rb:7:in `define'
    from /path/to/git/my_project/spec/support/factories.rb:3:in `<top (required)>'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/activesupport-3.2.8/lib/active_support/dependencies.rb:251:in `require'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/activesupport-3.2.8/lib/active_support/dependencies.rb:251:in `block in require'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/activesupport-3.2.8/lib/active_support/dependencies.rb:236:in `load_dependency'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/activesupport-3.2.8/lib/active_support/dependencies.rb:251:in `require'
    from /path/to/git/my_project/spec/spec_helper.rb:12:in `block in <top (required)>'
    from /path/to/git/my_project/spec/spec_helper.rb:12:in `each'
    from /path/to/git/my_project/spec/spec_helper.rb:12:in `<top (required)>'
    from /path/to/git/my_project/spec/controllers/service/competencies_controller_spec.rb:1:in `require'
    from /path/to/git/my_project/spec/controllers/service/competencies_controller_spec.rb:1:in `<top (required)>'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/rspec-core-2.11.1/lib/rspec/core/configuration.rb:780:in `load'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/rspec-core-2.11.1/lib/rspec/core/configuration.rb:780:in `block in load_spec_files'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/rspec-core-2.11.1/lib/rspec/core/configuration.rb:780:in `map'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/rspec-core-2.11.1/lib/rspec/core/configuration.rb:780:in `load_spec_files'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/rspec-core-2.11.1/lib/rspec/core/command_line.rb:22:in `run'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/rspec-core-2.11.1/lib/rspec/core/runner.rb:69:in `run'
    from /path/to/.rvm/gems/ruby-1.9.3-p194@my_project/gems/rspec-core-2.11.1/lib/rspec/core/runner.rb:8:in `block in autorun'

In all of the new documentation callbacks don't appear to be needed for traits, etc., but I'm guessing that to avoid interdependency issues between factories, I need to do something?

I'm sure this is really simple so sorry if I missed something.

Note: I'm trying to generate the factories now in Stepford, so if you want to try it with your schema to test it (which probably isn't necessary), try this.

Add this to Gemfile (along with 'factory_girl_rails', in an app with realistic schema and models):

gem 'stepford', :git => 'git://github.com/garysweaver/stepford.git'

then:

bundle install

then generate a factories.rb in Stepford (note you can also generate as individual files for each model):

bundle exec stepford factories --single --path ./replace_your_factories_with_this_temporarily.rb --exclude-all-ids --association-traits --attribute-traits

Then take a look at ./replace_your_factories_with_this_temporarily.rb and maybe temporarily swap it with your factories files/factories.rb.

Stepford is also in rubygems, but not this version with the traits stuff. It still needs some work, but it isn't supposed to be a complete replacement for writing factories yourself by any means, and is still in development currently.

Thanks!
Gary

Keenan Brock

unread,
Nov 5, 2012, 3:37:24 PM11/5/12
to factor...@googlegroups.com
Hi Gary,

create_list wants to be in an after_save hook.
to do this, I add an ignore variable.
it is a little redundant, would love to hear someone else's formula

factory :bar do
  ignore do
    create_foos false
  end

  trait :with_foos do
    create_foos true
  end

  after_create do |alert, evaluator|
    FactoryGirl.create_list :foo, 2 if create_foos
  end
end

Often, I do the opposite, setting the default to true, and have a trait :without_foos
Or you could use create_foos as a counter - (2 in your example)

--Keenan
--
Individuals over processes. Interactions over tools. Agile Rails training from thoughtbot, the makers of Clearance, Shoulda, & Factory Girl:
http://thoughtbot.com/services/training
 
You received this message because you are subscribed to the "factory_girl" mailing list.
To post to this group, send email to factor...@googlegroups.com
To unsubscribe from this group, send email to
factory_girl...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/factory_girl?hl=en

Gary Weaver

unread,
Nov 5, 2012, 6:27:57 PM11/5/12
to factor...@googlegroups.com
Thanks! That was it!

Also added caching as option to avoid circular references:
https://github.com/garysweaver/stepford
Reply all
Reply to author
Forward
0 new messages