Ecto doesn't save decimal value to correct precision

Hi,
I’m exploring Elixir and Phoenix framework.

I’m using phx.gen.html command to generate a simple CRUD resources. I’m using :decimal for price attract. And in the form html.eex, I use <%= number_input f, :price, step: "0.01". Apparently, updating this will always get rounded to integer.

Why is that?

How is the field :price defined in your schema?

(I assume there is a schema since you mentioned a CRUD resource).

Defined with :decimal like this:

field :price, :decimal

What value was specified for scale when creating the column in a migration? If it isn’t specified, it defaults to 0, which would give the exact “round to integer” behavior you’re seeing :thinking:

“Apparently”? Do you have a failing test? Can you show the changeset code along with sample inputs and output?

1 Like

Yes. In fact, the test always failed. Although I didn’t make any modification yet. Here’s the stack trace:

     code:  assert MasterData.get_item!(item.id) == item
     left:  %StxInventory.MasterData.Item{
              __meta__: #Ecto.Schema.Metadata<:loaded, "items">,
              code: "some code",
              group: %StxInventory.MasterData.ItemGroup{
                __meta__: #Ecto.Schema.Metadata<:loaded, "item_groups">,
                code: "some code",
                id: 153,
                inserted_at: ~N[2021-02-19 03:15:58],
                name: "some name",
                updated_at: ~N[2021-02-19 03:15:58]
              },
              group_id: 153,
              id: 42,
              inserted_at: ~N[2021-02-19 03:15:58],
              name: "some name",
              sell_price: #Decimal<121>,
              unit: "some unit",
              updated_at: ~N[2021-02-19 03:15:58]
            }
     right: %StxInventory.MasterData.Item{
              __meta__: #Ecto.Schema.Metadata<:loaded, "items">,
              code: "some code",
              group: %StxInventory.MasterData.ItemGroup{
                __meta__: #Ecto.Schema.Metadata<:loaded, "item_groups">,
                code: "some code",
                id: 153,
                inserted_at: ~N[2021-02-19 03:15:58],
                name: "some name",
                updated_at: ~N[2021-02-19 03:15:58]
              },
              group_id: 153,
              id: 42,
              inserted_at: ~N[2021-02-19 03:15:58],
              name: "some name",
              sell_price: #Decimal<120.5>,
              unit: "some unit",
              updated_at: ~N[2021-02-19 03:15:58]
            }

As you can see, the problem was left.sell_price and right.sell_price.

If it helps, my environment is the following:

  • MySQL v8.0.23 (Homebrew)
  • Elixir 1.11.3

It isn’t specified, what should be the value here?

Just check in your database then. Show us the column specification.

Your example is incrementing price in steps of 0.01, so I’d start by setting scale to 2.

2 Likes