factory_bot_rails: 6.3.0: `NoMethodError: undefined method '<' for nil:NilClass` when using a factory with traits

Description

After upgrading to 6.3.0, specs with traits started failing.

Downgrade to 6.2.0 works.

The problem seems to be triggered here:

https://github.com/thoughtbot/factory_bot_rails/blob/3346305320df35eadae4ac942e44fa7adbbfa574/lib/factory_bot_rails/factory_validator/active_record_validator.rb#L7

for_class is nil because the payload contains class: nil

Reproduction Steps

Please checkout the branch https://github.com/diowa/ruby3-rails7-bootstrap-heroku/tree/tmp/factory-bot-rails-issue

and run bundle exec rspec spec/model/user_spec.rb

Relevant commit: https://github.com/diowa/ruby3-rails7-bootstrap-heroku/commit/3c839031021362139ec9819bb51fdc861b337dcb

Expected behavior

Objects being created as 6.2.0

Actual behavior

       expected no Exception, got #<NoMethodError: undefined method `<' for nil:NilClass> with backtrace:
         # ~/.rvm/gems/ruby-3.2.2/gems/factory_bot_rails-6.3.0/lib/factory_bot_rails/factory_validator/active_record_validator.rb:7:in `block in validate!'
         # ~/.rvm/gems/ruby-3.2.2/gems/factory_bot-6.4.0/lib/factory_bot/attribute_list.rb:19:in `each'
         # ~/.rvm/gems/ruby-3.2.2/gems/factory_bot-6.4.0/lib/factory_bot/attribute_list.rb:19:in `each'
         # ~/.rvm/gems/ruby-3.2.2/gems/factory_bot_rails-6.3.0/lib/factory_bot_rails/factory_validator/active_record_validator.rb:6:in `validate!'
         # ~/.rvm/gems/ruby-3.2.2/gems/factory_bot_rails-6.3.0/lib/factory_bot_rails/factory_validator.rb:27:in `block (2 levels) in rails_6_0_support'
         # ~/.rvm/gems/ruby-3.2.2/gems/factory_bot_rails-6.3.0/lib/factory_bot_rails/factory_validator.rb:27:in `each'
         # ~/.rvm/gems/ruby-3.2.2/gems/factory_bot_rails-6.3.0/lib/factory_bot_rails/factory_validator.rb:27:in `block in rails_6_0_support'
         # ~/.rvm/gems/ruby-3.2.2/gems/factory_bot-6.4.0/lib/factory_bot/definition.rb:61:in `compile'
         # ~/.rvm/gems/ruby-3.2.2/gems/factory_bot-6.4.0/lib/factory_bot/definition.rb:169:in `aggregate_from_traits_and_self'
         # ~/.rvm/gems/ruby-3.2.2/gems/factory_bot-6.4.0/lib/factory_bot/definition.rb:36:in `to_create'
         # ~/.rvm/gems/ruby-3.2.2/gems/factory_bot-6.4.0/lib/factory_bot/trait.rb:17:in `to_create'
         # ~/.rvm/gems/ruby-3.2.2/gems/factory_bot-6.4.0/lib/factory_bot/definition.rb:174:in `map'
         # ~/.rvm/gems/ruby-3.2.2/gems/factory_bot-6.4.0/lib/factory_bot/definition.rb:174:in `aggregate_from_traits_and_self'
         # ~/.rvm/gems/ruby-3.2.2/gems/factory_bot-6.4.0/lib/factory_bot/definition.rb:36:in `to_create'
         # ~/.rvm/gems/ruby-3.2.2/gems/factory_bot-6.4.0/lib/factory_bot/definition_hierarchy.rb:6:in `build_from_definition'
         # ~/.rvm/gems/ruby-3.2.2/gems/factory_bot-6.4.0/lib/factory_bot/factory.rb:125:in `build_hierarchy'
         # ~/.rvm/gems/ruby-3.2.2/gems/factory_bot-6.4.0/lib/factory_bot/factory.rb:88:in `compile'
         # ~/.rvm/gems/ruby-3.2.2/gems/factory_bot-6.4.0/lib/factory_bot/factory.rb:32:in `run'
         # ~/.rvm/gems/ruby-3.2.2/gems/factory_bot-6.4.0/lib/factory_bot/factory_runner.rb:29:in `block in run'
         # ~/.rvm/gems/ruby-3.2.2/gems/factory_bot-6.4.0/lib/factory_bot/factory_runner.rb:28:in `run'
         # ~/.rvm/gems/ruby-3.2.2/gems/factory_bot-6.4.0/lib/factory_bot/strategy_syntax_method_registrar.rb:28:in `block in define_singular_strategy_method'
         # ./spec/model/user_spec.rb:8:in `block (3 levels) in <top (required)>'
         # ./spec/model/user_spec.rb:7:in `block (2 levels) in <top (required)>'
         # ~/.rvm/gems/ruby-3.2.2/gems/webmock-3.19.1/lib/webmock/rspec.rb:39:in `block (2 levels) in <top (required)>'

System configuration

factory_bot_rails version: 6.3.0 factory_bot version: 6.4.0 rails version: 7.1.2 ruby version: 3.2.2

About this issue

  • Original URL
  • State: closed
  • Created 7 months ago
  • Reactions: 40
  • Comments: 20 (3 by maintainers)

Commits related to this issue

Most upvoted comments

Thank you to @makicamel for stepping up with a second fix, with great tests. This fix is released as 6.4.2.

Sorry, the 6.4.2 release of factory_bot, which factory_bot_rails depends on. If you bundle update factory_bot it should pull in the latest dependency.

After upgrading to factory_bot 6.4.1 and factory_bot_rails 6.4.0, I’m still seeing the undefined method < for nil:NilClass error from lib/factory_bot_rails/factory_validator/active_record_validator.rb:7:in block in validate! when using a mixin trait, e.g.

# In the factory definition...
FactoryBot.define do
  factory :magazine do
    # ...
  end

  trait :with_latest_issue do
    # ...
  end
end

# And then in a spec...
create(:magazine, :with_latest_issue)

Adding a debugger after line 5 of the ActiveRecordValidator shows that the payload Hash passed to validate!(payload) for the :with_latest_issue trait has the :class key set to nil.

FWIW, bumping to factory_bot (6.4.1) and factory_bot_rails (6.4.0) did resolve this issue on my repo. Thanks for the quick (partial?) fix!