RubyMoney/money

Rails "monetize": Passing in a value with thousands seperator, but without decimal separator leads to wrong amount

stex opened this issue ยท 1 comments

stex commented

Hey ๐Ÿ˜ƒ

I'm using Money with attributes backed by decimal columns as I needed fractions of cents and didn't think of defining an own currency.

I noticed a strange behaviour today: With the "EUR" currency, Money usually formats and parses strings using the correct thousands and decimal limiters, e.g. "1.000,00".

However, when being given values without any decimal value, it seems to interpret the string as a float and removes everything after the dot - "1.000" becomes 1.0.

Is this the expected behaviour and I misconfigured something?

I wrote a short test for this behaviour:

#!/usr/bin/env ruby

require "bundler/inline"

gemfile(true) do
  source "https://rubygems.org"

  gem "rails"
  gem "sqlite3"
  gem "money-rails"
end

require "active_record"
require "active_support/all"
require "minitest/autorun"
require "logger"
require "money-rails"

# Money Configuration

Money.default_infinite_precision = true

MoneyRails.configure do |config|
  config.default_currency = :eur

  config.amount_column = { prefix: "",
    postfix: "_cents",
    column_name: nil,
    type: :decimal,
    present: true,
    null: false,
    default: 0 }

  config.currency_column = { prefix: "",
    postfix: "_currency",
    column_name: nil,
    type: :string,
    present: true,
    null: false,
    default: "EUR" }
end

ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Base.logger = Logger.new(STDOUT)

MoneyRails::Hooks.init

ActiveRecord::Schema.define do
  create_table :money_models, force: true do |t|
    t.monetize :amount
  end
end

class MoneyModel < ActiveRecord::Base
  monetize :amount_cents
end

class BugTest < Minitest::Test
  def test_money_parsing
    record = MoneyModel.new

    record.amount = "1000,00"
    assert_equal 1000.0, record.amount.to_f

    record.amount = "1.000,00"
    assert_equal 1000.0, record.amount.to_f

    record.amount = "1.000"
    assert_equal 1000.0, record.amount.to_f

    # Failure:
    # BugTest#test_money_parsing [money-test.rb:69]:
    # Expected: 1000.0
    #   Actual: 1.0
  end
end
stex commented

I just saw that I had the wrong tab open when creating the issue and didn't create it in money-rails ๐Ÿ™ˆ
I'll move it there.