ruby-on-railsruby-on-rails-4simple-formsimple-form-for

simple_from_for with decimal precision doesn't save decimals


I am using simple_form_for for my form template which is not storing decimal numbers into my database table. When I submit the form, it throws away the precision.

Here is what I have:

my schema.rb

create_table "coupons", force: true do |t|
    t.decimal  "amount", precision: 10, scale: 0
end

new.html.slim

.panel-body.padded
        = simple_form_for @coupon, :url => admin_coupons_path  do |f|
          .form-group
            = f.input :amount, as: :string, input_html: { value: number_with_precision(f.object.amount, precision: 8) }, required: true

database image

enter image description here

Am confused as to what else I can do to make that work. Any help will be appreciated.


Solution

  • The missing piece to the puzzle is the precision of the decimal within the database. By default, the code above will create a decimal field in MySQL with 10 digits, all of which are to the left of the decimal point. In other words, saving 15.37 to your model will show 15.37 within the app, but when you save it, it’ll become 15 both in the data store and when you reload it.

    The way around this is to specify the precision and the scale in your migration. So correct it with a followup migration:

    change_column :table_name_in_plural, :column_name, :decimal, :precision => 10, :scale => 2
    

    In this case, we’ve set the total number of digits (the precision) to 10, with 2 decimal places (the scale.) Note that you can pick your sizes as per your needs – MySQL docs give some guidelines to the storage requirements for different combinations.

    Also, when picking your precision and scale, be aware that the scale (max decimal places) can’t be greater than the precisions (total digits.) That might seem obvious when written here, but without those translations in parentheses, it’s easy to get lazy and make the two values the same, which would leave you with a number that has to be less than 1.0, since all the space will be allocated to the right of the decimal place.

    Reference: Here