shoulda-matchers: undefined method `type' for nil:NilClass when using validate_uniqueness_of(...).scoped_to(AnArray)
When using a validation like
validates :a_field, uniqueness: { scope: [:an_association, :another_association]
and running the test as
it { should validate_uniqueness_of(:a_field).scoped_to([:an_association, :another_association]) }
produces an error
Failure/Error: it { should validate_uniqueness_of(:a_field).scoped_to([:an_association, :another_association]) }
NoMethodError:
undefined method `type' for nil:NilClass
# shoulda-matchers-3.0.0/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb:473:in `dummy_scalar_value_for'
# shoulda-matchers-3.0.0/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb:468:in `dummy_value_for'
# shoulda-matchers-3.0.0/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb:441:in `block in validate_after_scope_change?'
# shoulda-matchers-3.0.0/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb:436:in `each'
# shoulda-matchers-3.0.0/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb:436:in `all?'
# shoulda-matchers-3.0.0/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb:436:in `validate_after_scope_change?'
# shoulda-matchers-3.0.0/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb:266:in `matches?'
About this issue
- Original URL
- State: closed
- Created 9 years ago
- Reactions: 22
- Comments: 53 (7 by maintainers)
Commits related to this issue
- Skip test due to a bug in Shoulda Matchers 3 Skip test until bug is solved: https://github.com/thoughtbot/shoulda-matchers/issues/814 It is also needed to use the new qualifier `ignoring_case_sensit... — committed to openSUSE/osem by Ana06 6 years ago
- Skip test due to a bug in Shoulda Matchers 3 Skip test until bug is solved: https://github.com/thoughtbot/shoulda-matchers/issues/814 It is also needed to use the new qualifier `ignoring_case_sensit... — committed to openSUSE/osem by Ana06 6 years ago
- Skip test due to a bug in Shoulda Matchers 3 Skip test until bug is solved: https://github.com/thoughtbot/shoulda-matchers/issues/814 It is also needed to use the new qualifier `ignoring_case_sensit... — committed to openSUSE/osem by Ana06 6 years ago
- Skip test due to a bug in Shoulda Matchers 3 Skip test until bug is solved: https://github.com/thoughtbot/shoulda-matchers/issues/814 It is also needed to use the new qualifier `ignoring_case_sensit... — committed to openSUSE/osem by Ana06 6 years ago
- Skip test due to a bug in Shoulda Matchers 3 Skip test until bug is solved: https://github.com/thoughtbot/shoulda-matchers/issues/814 It is also needed to use the new qualifier `ignoring_case_sensit... — committed to openSUSE/osem by Ana06 6 years ago
- upgrade shoulda-matchers to resolve deprecation The version we were using was quite old and suffered a deprecation warning in later Ruby 2.6 about BigDecimal.new() vs BigDecimal(). Moving to Ruby 2.7... — committed to chef/supermarket by robbkidd 4 years ago
- upgrade shoulda-matchers to resolve deprecation The version we were using was quite old and suffered a deprecation warning in later Ruby 2.6 about BigDecimal.new() vs BigDecimal(). Moving to Ruby 2.7... — committed to chef/supermarket by robbkidd 4 years ago
- Add comment about no support of validate_uniqueness_of(:item).scoped_to(array) Closes #814 — committed to gmmcal/shoulda-matchers by gmmcal 4 years ago
- Add comment about no support of validate_uniqueness_of(:item).scoped_to(array) Closes #814 — committed to gmmcal/shoulda-matchers by gmmcal 4 years ago
- Add comment about no support of validate_uniqueness_of(:item).scoped_to(array) Closes #814 — committed to thoughtbot/shoulda-matchers by gmmcal 4 years ago
+1 Having the exact same issue as the others. I had a Active Record 5 related issue so I thought this might be related to using Active Record 5, but it seems that this is not the case.
Any chance of a release soon? Been about a half a year since the last update…
Same here… we had worked around this in 2.x by using association**_id**:
it { is_expected.to validate_uniqueness_of(:a_field).scoped_to(:association_id).case_insensitive}However, moving to 3.1.1 just now has removed that:
Just use the association_id validates_uniqueness_of :a_field, scope: :association_id
I was able to get this to work when using attributes on the table itself:
If you’re willing to live with the attributes v. association object, this will pass
Unfortunately, there’s so much stuff that we are including in the next release that we’ve decided to hold off on fixing this for now. I’ll keep this open for now but we’ll have to swing back around and include a fix for this in a future release.
if someone needs a temporary workaround for that:
I’ve been noodling on this the past few days. The reason why we haven’t tackled this problem yet is it’s a difficult problem, and it’s difficult because because associations are way more variable than non-associations. The most complicated part of the uniqueness matcher is that it needs to generate unique values for the attributes that are involved in the validation (or at least the ones you care about), so that it can test the validation thoroughly. For instance, if you have a Post model and it validates uniqueness of
slugscoped toblog_id, it tests these scenarios:slugandblog_id— does the validation fail?slugbut the sameblog_id— does the validation pass?slugbut a differentblog_id— does the validation pass?To do this, the uniqueness matcher needs to know how to generate a record with a “different” (i.e. unique) value for one or more attributes. This is relatively easy to do for non-associations: if the attribute is a string column, call
.nexton the string; if it’s a number column, add 1; if it’s a time column, add 1 second; etc. But associations are totally separate ActiveRecord objects, and while the simplest way to create a unique version of another record is to.dupit and save it to get an object with a different id, that’s probably not going to work, especially if that model has a uniqueness validation on it. Maybe the matcher could do something like look inside that model, see which attributes are unique, and try to generate unique values for those attributes — but that would add complexity I don’t think we need. It’s probably less code and a better experience in the long run to have you as the developer provide unique values for association attributes through another qualifier. I’m thinking that this could look something like this:and if you had multiple association scopes:
I don’t have any code written to support this yet as I’m still playing around with this. Would this seem like a good solution, though?
I’m running into this same bug with a validation intended to prevent accidentally creating two identical relationships. Wound up just checking the IDs rather than the related object to work around.
Will create a PR then
I’m not even sure if this issue still occurs. I’ve first opened this error because it failed to validate scoped to more than one association at the same time. I do vaguely remember that scoping to a single association worked at the moment in time. I’ll try to create a demo app that reproduces this error, so we are clear in it. Based on comments, I think we potentially have 2 issues in a single place. I’ll come back with demo repository whenever I have it.
+1
I am seeing this even without
scoped_toon any association, just a basic uniqueness validation:Just experienced this, bit of a bummer 👍
The uniqueness matcher doesn’t support using associations as scopes. I’m not really sure this is what you want to do, anyway – don’t you want to use id columns instead?
@bbugh I think you might be right about that, I have definitely noticed some oddities in the past. I will put this in the queue for the next version.
+1