Fix thousand separator issue in validation#712
Fix thousand separator issue in validation#712RubenIgnacio wants to merge 14 commits intoRubyMoney:mainfrom
Conversation
e060d29 to
dc4bc08
Compare
cd76259 to
f4b603d
Compare
f4b603d to
93df31e
Compare
Co-authored-by: Sunny Ripert <sunny@sunfox.org>
…efining product setup
93df31e to
1bfd1bd
Compare
|
Hi @RubenIgnacio this is a bit hard to review as it mixes a fix as well as multiple linting changes. Ideally we would split the lint changes into their own PRs, see also RubyMoney/money#1134 🙏🏻 |
You're right, I made some extra changes in the middle. I can create a PR first to organize the RSpec file, and then another one for the fix. I did the reorganization because I had trouble finding where to put my changes at first, but let me know if you'd prefer I only focus on the fix. |
|
Ideally I’d say to go for the fix first as we will soon do a new release and it would be nice to include this if we can. As for the lint changes, the best would be to split it into several PRs if possible. |
|
ok, got it, I'll start from scratch to keep the history clean and take the chance to improve the fix, should I force-push the fix to this same branch or close this PR and open a new one? I'll handle the linting changes in separate PRs afterwards. |
|
Thank you 🙏🏻
As you wish! |

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_eachmethod is invoked to verify whetherraw_value.nil? && record.public_send(subunit_attr)is true. When this condition is true,raw_valueis calculated assubunit_value.to_f / currency.subunit_to_unit, resulting in a float value.Subsequently, when the
generate_detailsmethod is called, it determines the currency's thousand separator in order to instantiate theDetailsobject. For currencies that use a dot (.) as a thousand separator, theDetailsobject, when passed to thenormalizemethod, converts theraw_valueto a string and removes the thousand separator.This conversion process results in the original float value of
120.0forraw_valuebeing 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: