Fix thousand separator issue in validation #712
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
When validating a model with a monetized field retrieved from the database, a validation error is raised if the field is not set before the model is validated when a validation with a limit is applied, regardless of whether the monetized field already has a value. For example:
This issue occurs specifically with currencies that use a dot (.) as a thousand separator, such as EUR. Consider a scenario where a product with a price of 1,200 EUR is retrieved from the database. When attempting to validate it, a validation error occurs due to the numericality limit:
During the validation process, the
MoneyValidator#validate_each
method is invoked to verify whetherraw_value.nil? && record.public_send(subunit_attr)
is true. When this condition is true,raw_value
is calculated assubunit_value.to_f / currency.subunit_to_unit
, resulting in a float value.Subsequently, when the
generate_details
method is called, it determines the currency's thousand separator in order to instantiate theDetails
object. For currencies that use a dot (.) as a thousand separator, theDetails
object, when passed to thenormalize
method, converts theraw_value
to a string and removes the thousand separator.This conversion process results in the original float value of
120.0
forraw_value
being transformed into the string'120.0'
. However, after the thousand separator is removed, this string is misinterpreted as'12000'
, ultimately resulting in a validation failure when a numericality limit is enforced.Proposed Solution
Replace the following code:
with this code:
This change ensures that if the before_type_cast attribute is nil, the method will call the attribute directly to retrieve the current value. Since the retrieved value is a Money object, it is correctly formatted when converted to a string, avoiding the issue caused by misinterpretation of the thousand separator.
Changes included in this PR: