Postgres and Grape::Entities: Decimals appear as strings

Sometimes grape-entity needs a little help figuring out the correct data type for model attributes. Take the following example, when using PostgreSQL as the backing DB :cost is returned as a (string)”10.5″ instead of the (float)10.5. Although you could handle this fairly quickly on the UI side (new Number() comes to mind) it’s better to return the correct data types in the API.

  class Foo < ActiveRecord::Base
  // cost :decimal(6, 2)
  end

  class FooEntity < Grape::Entity
    expose :cost
  end

  // GET /foos/1
  // { cost: "10.5" }

So why does this happen? It’s all about printing objects. PostgreSQL returns decimals as BigInteger objects instead of native floats. This causes grape-entity to output the BigDecimal object using to_s.

Getting around this is fairly simple though. By overriding the :cost attribute we can coerce our :cost attribute into a float.

class FooEntity < Grape::Entity
  expose :cost
  def cost
    object.cost.to_f
  end
end

// GET /foos/1
// { cost: 10.5 }

P.S. If you’re a fan of grape and haven’t tried out grape-entity you’re missing out! It’s a great way of creating reusable object definitions when outputting data from your grape-based APIs.

Leave a Reply