简体   繁体   中英

Creating a FactoryGirl definition that uses a currently seeded record

I've had the same problem as raised in FactoryGirl's GitHub page ( #623 ) with a uniqueness validation being tripped via seeded data.

My factory originally looked like this:

factory :country, class: MyApp::Models::Country do
  code { MyApp::Models::Country.first.code }
  name { MyApp::Models::Country.first.name }
end

Not ideal and broke the linter, so I've refactored using the suggestion in #623:

factory :country, class: MyApp::Models::Country do
  intitalize_with { MyApp::Models::Country.find_or_create_by(code: 'GB') }
end

However I now get the following error stack on linting:

/Users/philostler/.rvm/gems/ruby-2.1.2/gems/activemodel-4.1.4/lib/active_model/attribute_methods.rb:435:in `method_missing': undefined method `intitalize_with=' for #<MyApp::Models::Country id: nil, code: nil, name: nil> (NoMethodError)
    from /Users/philostler/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.4/lib/active_record/attribute_methods.rb:208:in `method_missing'
    from /Users/philostler/.rvm/gems/ruby-2.1.2/gems/factory_girl-4.4.0/lib/factory_girl/attribute_assigner.rb:16:in `block (2 levels) in object'
    from /Users/philostler/.rvm/gems/ruby-2.1.2/gems/factory_girl-4.4.0/lib/factory_girl/attribute_assigner.rb:15:in `each'
    from /Users/philostler/.rvm/gems/ruby-2.1.2/gems/factory_girl-4.4.0/lib/factory_girl/attribute_assigner.rb:15:in `block in object'
    from /Users/philostler/.rvm/gems/ruby-2.1.2/gems/factory_girl-4.4.0/lib/factory_girl/attribute_assigner.rb:14:in `tap'
    from /Users/philostler/.rvm/gems/ruby-2.1.2/gems/factory_girl-4.4.0/lib/factory_girl/attribute_assigner.rb:14:in `object'

It's now trying to invoke intitalize_with= on a blank model object which of course will fall over.

I simply want the factory to use a already present record while still passing the lint.

Am I going about this the wrong way or is there a bug here (possibly because I'm using namespaces)?

Often I encounter weird error with non-relevant message while using FactoryGirl and declaring the class using constant, as you are doing. Using string fixes the situation on my side, this is certainly auto loading related.

I don't know if that is your solution, but you can try (do it for all your factories)

# Instead of
factory :country, class: MyApp::Models::Country do
  code { MyApp::Models::Country.first.code }
  ...
end

# Do
factory :country, class: 'MyApp::Models::Country' do
  code { MyApp::Models::Country.first.code }
  ...
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM