Leveraging Rails' Money Type
You have a Rails application and need to persist some data through a form which has a JavaScript money mask.
Here in Brazil for instance, we format money this way: R$ 1.000,90.
Given this is a string and we need to save as decimal or integer, we have to convert.
class String
# Convert a money string ('R$ 10.000,00') to float (10000.0)
def clean_money
self.gsub(/[^\d,]/, '').gsub(',', '.').strip.to_f
end
end
The clean_money
above solves the problem, however, we always have to call it before set our data in the model (not that DRY).
Looking for a better way to do it I found two good solutions:
- Create your column as
money
type (Rails 4.2+) - Use the new attributes API (Rails 5+)
Both solutions only work if you are using PostgreSQL.
Column as money type
class CreateProducts < ActiveRecord::Migration
def change
create_table :products do |t|
t.money :price
end
end
end
Attributes API
class CreateProducts < ActiveRecord::Migration
def change
create_table :products do |t|
t.decimal :price
end
end
end
class Product < ApplicationRecord
attribute :price, :money # will behave like money type
end
You just need it, really.
Then we can pass strings straight to our models:
Product.create(price: "R$ 50,80")
puts Product.last.price
# 50.8
Product.create(price: "$ 10,000.80")
puts Product.last.price
# 10000.8
See you.
Written on December 13, 2016