shoulda-matchers: `should have_many().through` gives `undefined method `class_name' for nil:NilClass`

I’ve just run into a problem with shoulda-matchers 2.7.0 and 2.8.0, Rails 4.2, and Ruby 2.2.0 on Mac OS X 10.10. The complete application is at https://github.com/marnen/duckbill/tree/shoulda-matchers-issue , if you need to see the code in context.

Here’s the relevant code:

# user.rb
has_many :clients
has_many :projects, through: :clients
# user_spec.rb
it { should have_many :clients }
it { should have_many(:projects).through :clients }

I would expect both specs to pass, but only the first one does. The second one gives the following error:

Failures:

  1) User should have many projects through clients
     Failure/Error: it {  should have_many(:projects).through :clients }
     NoMethodError:
       undefined method `class_name' for nil:NilClass
     # /Users/marnen/.rvm/gems/ruby-2.2.0/gems/activerecord-4.2.0/lib/active_record/reflection.rb:871:in `derive_class_name'
     # /Users/marnen/.rvm/gems/ruby-2.2.0/gems/activerecord-4.2.0/lib/active_record/reflection.rb:147:in `class_name'
     # /Users/marnen/.rvm/gems/ruby-2.2.0/gems/shoulda-matchers-2.8.0/lib/shoulda/matchers/active_record/association_matcher.rb:1067:in `rescue in class_exists?'
     # /Users/marnen/.rvm/gems/ruby-2.2.0/gems/shoulda-matchers-2.8.0/lib/shoulda/matchers/active_record/association_matcher.rb:1064:in `class_exists?'
     # /Users/marnen/.rvm/gems/ruby-2.2.0/gems/shoulda-matchers-2.8.0/lib/shoulda/matchers/active_record/association_matcher.rb:928:in `matches?'
     # ./spec/models/user_spec.rb:5:in `block (2 levels) in <top (required)>'

I have no idea what’s going on here. Is this a Rails 4.2 incompatibility? Or something else? Help?

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Comments: 16 (4 by maintainers)

Most upvoted comments

Apparently, the problem was that while I had done User.has_many :projects, through: :clients, I had not declared Client.has_many :projects. Leaving this open because a more informative error message might be helpful.

This will also occur if you don’t define a proper belongs_to association in the model you’re going through.