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

Decimals set to values over precision and scale get truncated to 0.0 #26108

Closed
violetaria opened this Issue Aug 10, 2016 · 4 comments

Comments

Projects
None yet
3 participants
@violetaria
Copy link

violetaria commented Aug 10, 2016

What I'm seeing in Rails 5.0.0 vs previous version of Rails 4.2.1 is that decimal values get truncated once they go over the scale and precision set in the DB.

Steps to reproduce

Code to reproduce the error

begin
  require "bundler/inline"
rescue LoadError => e
  $stderr.puts "Bundler version 1.10 or later is required. Please update your Bundler"
  raise e
end

gemfile(true) do
  source "https://rubygems.org"
  gem "rails", github: "rails/rails"
  gem "sqlite3"
  gem 'pry'
end

require "active_record"
require "minitest/autorun"
require "logger"

# This connection will do for database-independent bug reports.
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Base.logger = Logger.new(STDOUT)

ActiveRecord::Schema.define do
  create_table :things, force: true do |t|
   t.decimal :price, precision: 4, scale: 4
  end

end

class Thing < ActiveRecord::Base
end


class BugTest < Minitest::Test
  def test_association_stuff
    thing = Thing.create!
    thing.price = 0.0001
    assert_equal '0.0001', thing.price.to_s

    thing.price = 0.00001
    assert_equal '0.00001', thing.price.to_s
  end
end

Expected behavior

I have a validation that looks like this which works in previous version of Rails

format: { with: /\A\d+(?:\.\d{0,4})?\z/ }, numericality: { greater_than_or_equal_to: 0, less_than: 1 }

When set to 0.0001 everything works as expected, but when set to 0.00001 the validation should fail because it doesn't match the format.

Actual behavior

The value gets truncated to 0.0 which is making the validation pass.

System configuration

Rails version: Rails 5.0.0

Ruby version: ruby 2.2.2p95

@violetaria

This comment has been minimized.

Copy link
Author

violetaria commented Aug 15, 2016

I've found a the correct way to validate this type of data here: #23400

TLDR: use the attribute_before_type_cast to do custom validations when your DB has scale and precisions value defined for decimals. DB scale and precision are applied to value at time of save but you can get the previous values using before_type_cast.

@prakashmurthy

This comment has been minimized.

Copy link
Contributor

prakashmurthy commented Aug 16, 2016

I think this issue should be closed. The rounding is as expected based on the scale and precision set in the database. The commit that changed this behavior - fixing the original bug - is 0b94384

@violetaria

This comment has been minimized.

Copy link
Author

violetaria commented Aug 16, 2016

I agree it's not a bug and can be closed. It just was not clear to me how to implement validations on data until I found the other issue. Perhaps there could be some more information added to the documentation on this.

@rafaelfranca

This comment has been minimized.

Copy link
Member

rafaelfranca commented Aug 17, 2016

@violetaria yeah, documenting it would be great since you already have the context about the problem could you open a pull request? thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment