yellowreign
yellowreign

Reputation: 3638

How to format a price correctly regardless of decimal format

I want it to be able to read in JSON and save it correctly regardless whether the value is 44.5, 44 or 44.99. The price attributes are a decimal format.

The error is happening in the convert_price method. The price in the JSON response can be 44, 44.50 or 44.99. However, I noticed that sometimes the last decimal is cut off, like in the error 44.5.

I'm receiving this error:

undefined method 'match' for float 74.5:Float

My code is:

# read in JSON and create books
def create_item
  job_items_url = "https://foobar.com&format=json"
  response = open(job_items_url).read.to_s
  books = JSON.parse(response)

  Book.create(reg_price: convert_price(item['reg_price']),
    sale_price: convert_price(item['sale_price']))
  end

# format the price
def convert_price(price)
  return nil if price.blank? || price.to_f.zero?
  price = "#{price}.00" unless price.match(/[,.]\d{2}\z/)
  price.delete(',.').to_f / 100
end

Upvotes: 0

Views: 138

Answers (2)

Kache
Kache

Reputation: 16687

It looks like price is already a Numeric object. Check out sprintf for simple Type-aware padding, for example:

sprintf('%.2f', 44.5) # => "44.50"

# so you should do something like this:
sprintf('%.2f', price.to_f)

A suggestion:

def try_format_currency(price)
  sprintf('%.2f', Float(price))
rescue => ex
  # log error if you want
  nil
end
  • Use Float() conversion, which can raise, which will clearly express that price is "untrustworthy" input, and might not be a proper number
  • Express the same thing in the naming of the method

Upvotes: 0

gsumk
gsumk

Reputation: 891

You can use number_to_currency without a unit:

>> number_to_currency(45,unit:"")
=> "45.00"
>> number_to_currency(45.5,unit:"")
=> "45.50"
>> number_to_currency(45.55,unit:"")
=> "45.55"
>>

See number_to_currency for more information.

Upvotes: 1

Related Questions