-
Notifications
You must be signed in to change notification settings - Fork 1.4k
MONGOID-5842 validates_numericality_of is valid when allow_blank is true and string is assigned #6074
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR addresses MONGOID-5842 by fixing validation behavior when validates_numericality_of is used with allow_blank: true and a non-numeric string is assigned to a numeric field. The fix ensures that non-numeric strings are properly validated as invalid, rather than being coerced to nil/0 before validation.
Key Changes
- Modified
read_attribute_for_validationto return the pre-type-cast value for BigDecimal, Float, and Integer fields - Added comprehensive test coverage for
allow_blank: truescenarios with both Integer and Float field types
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| lib/mongoid/validatable.rb | Added logic to return pre-type-cast values for numeric field types during validation |
| spec/mongoid/validatable/numericality_spec.rb | Added test cases for allow_blank: true validation behavior with Integer and Float fields |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
jamis
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice. Thank you for your work on this!
I know I suggested this solution, but I was thinking more about it this morning and I worry a bit about changing read_attribute_for_validation like this. It's a Rails API, not a Mongoid one, which means we don't have any control over how Rails decides to use it. A new version of Rails could easily call that method somewhere unexpected, and expect a numeric value to be returned for a numeric field. The default implementation of prepare_value_for_validation, for example, simply returns the value it is given.
At the core of the issue, and this incompatibility, is the fact that ActiveRecord returns 0, not nil, when a non-numeric value is set and allow_blank is true. It's also how Ruby itself works (e.g. "hello".to_i # => 0). I wonder if we ought to roll that change back, so that Mongoid mirrors this? The alternative is probably to subclass NumericalValidator and write our own #validate method, to accommodate the fact that Mongoid returns nil instead of 0, here.
We should discuss this as a team next week, but this is a very good example of what we're trying to do with the Mongoid X initiative: this used to work, and now it doesn't. Do we revert the change? Do we allow the change and find a way to work around it? Or do we say that the new way is correct and the old way is wrong, and we describe how people ought to update their apps to accommodate that?
So. Let's hold off on further work here until we know what we want to do. Thank you for your investigation on this!
I strongly, strongly vote against changing this. |
Co-authored-by: Jamis Buck <[email protected]>
Prior to this change, the validation for numericality was skipped if allow_blank was set to true and a string was provided. This happened because typecasting the string resulted in nil, which caused the validation check to be bypassed here. We have updated read_attribute_for_validation to return the original, non-typecasted value if typecasting to a numeric type fails.