I am facing an issue with Ruby BigDecimal on my Rails 4 app.
I have a "price" attribute in a Thing model, which class is BigDecimal. Whenever I create or update a Thing, I would like to save the "price" attribute with strictly two decimal digits (e.g. "0.00", "10.00", "10.10", "10.01").
But it saves, by default, only one decimal digit if two are not necessary. Here what I insert and what it saved currently :
"0" => "0.0" (instead of "0.00")
"10" => "10.0" (instead of "10.00")
"10.1" => "10.1" (instead of "10.10")
"10.01" => "10.01" (OK)
I don't just want to display the "price" attribute with two decimals (which can be done using "%.2f" % price), I want to save the "price" attribute with two decimal digits in my database. Any way to do so ?
Thanks a lot for your help.
What you are describing seems to me to be purely for display purposes. I don't know of any way to save a decimal to a DB with a specific amount of decimals that don't actually add precision unless you save them as a string.
Seems to me you would be best off creating a method on the Thing model that will return price formatted how you want.
Related
i have an issue for which i have not been able to find a specific solution for.
I have a Ruby on Rails Webapp that handles data entry of specific invoice amounts. Simply a form where a user can punch information from an invoice. The values are rather simple. id, Year, Month and then a bunch of amount fields.
When i first created the amount columns in the postgreSQL database, i didn't specify any precision and i didn't default the values to 0. I found out quickly that if i didn't want to assign 0 values to any nil returned from the form, it was better to assign a default value right away.
The issue i have is that when a new form (or the edit form) is rendered, in some browsers (not all) any 0.00 value shows as 0 or 0.0 even though my columns have a precision of 2 and i am formatting the value of the form field using :value => (number_with_precision(f.object.consulting, :precision => 2) || 0)
To make the matter worse, the same browser reacts differently on different platforms. Mozilla Firefox on my Ubuntu machine shows the values as 0.00 whereas FireFox on my windows machine shows the values as 0
When you do type a decimal such as 100.25, then both decimals are showing. If i were to type 100.20, only 100.2 would be shown.
Here is what i have:
In my table, columns are identified as such:
t.decimal "consulting", precision: 10, scale: 2, default: 0.0
In my view/form, i use the following code to display the column
<div class = "col-sm-5 col-md-5 col-lg-3">
<%=f.number_field :consulting, :step => 'any', :tabindex => 5 ,class: 'form-control text-right input-sm remit-sum', :value => (number_with_precision(f.object.consulting, :precision => 2) || 0.00) %>
</div>
I am not quite sure what i could do to fix the issue. I know that if i change the form field from
f.number_field to f.text_field
It works and displays properly. So i guess this is a 2 part question.
1)Ss there a way to consistently display 2 decimals using the number_field tag
2) What harm would it do and what kind of changes would it take to display and input the amouts using a text_field tag.
ps: I have tried using the number_to_currency method to no avail
So there a way to consistently display 2 decimals using the
number_field tag?
You can set step="0.01" unfortunately that also sets the step so that incrementing/decrementing with the buttons would only change the amount by 1ยข for euros or dollars. Which means you would have to tap it one hundred times on a smartphone to change the amount by one unit which is a fail.
Most browsers drop the trailing zeros as (0.00 = 0.0 = 0). You might just want to learn to live with basic mathematics.
What harm would it do and what kind of changes would it take to
display and input the amounts using a text_field tag.
Back in the day before HTML5 thats how it was done. You lose the native form controls and need to format the values with javascript - remember those clunky jQuery UI number selects?
I have a dynamically generated table that multiplies price * qty. Some of the prices are in partial cents. For example
if the price of an item is 0.0375 I can display that in my table as
number_to_currency(0.0375,:precision => 4)
=> $0.0375
but on quantities where the price is a standard 2 decimal number I get
number_to_currency(33.95,:precision => 4)
=> $39.9500
I need a way to trim the trailing zeroes of a decimal value. Keep in mind that the output is in a Model.each block so I'm uncertain I can modify the precision parameter conditionally.
Try to specify strip_insignificant_zeros option:
number_to_currency(33.95, precision: 4, strip_insignificant_zeros: true)
It should remove zeros after decimal separator. Here is description of this option.
The default for this method is 2. So you simply need
number_to_currency(33.95)
http://api.rubyonrails.org/classes/ActionView/Helpers/NumberHelper.html#method-i-number_to_currency
number_to_currency(33.95,:precision => 2)
Since number_to_currency returns a String, you can use .remove(/0+$/) to remove any trailing zeros:
number_to_currency(33.95,:precision => 4).remove(/0+$/)
Try using round before number_to_currency:
number_to_currency(33.95.round(4)) # $33.95
number_to_currency(0.0375.round(4)) # $0.0375
I am trying give decimal value to input field like - 10,235,333. It takes this value but as I move to next field, commas are removed from text field. Is there any way that commas will be left in the text field until I submit the form but when I submit the form only numbers will be stored in the database?
Thanks in advance..
I have got the solution for this issue. I got a jquery plugin for this that is jquery.number. This plugin automatically adds comma to your numbers.
This plug-in formats input value implicitly.
like if we type
10000 it formats this no to 10,000
for 1000 = 1,000
for 100000 = 100,000
for 1000000 = 1,000,000
you can override the setter method. Given a price field,
# model
def price=(num)
write_attribute :price, price.gsub(/[^\d]/, '')
end
Then in your view, you can format the value before you render the view
f.text_field :price, value: number_with_delimiter(f.object.price)
I'm storing numbers such as
2,000
5,000
10,000
in a database with an 'integer column'. When I display them on the app, they're showing up like
2.0
5.0
Is there a column type I can use to make them show up "as is." I tried string before but string doesn't sort well.
Integers should come out like integers. If you try to insert "2,000" internally rails is effectively doing to do a to_i on it which will be 2. (try this on irb "2,000".to_i and "2_000".to_i to see how ruby deals with integer conversions).
Now if you insert 2000 and you get 2000.0 that is not natural or expected for an integer column. I suspect there is some post processing going on on the attribute or that your database is decimal/float column.
Rails Console =>
"2,000".to_i => 2
"2_000".to_i => 2000
helper.number_to_currency(2000) => "$2,000.00"
to fix this, I entered the number in the database without the comma. Then the numbers showed up on the app like 10000.0 and I used number_to_currency to change the number to make it look like a dollar value
In Ruby, you can also enter in integers like this
10_000
5_000
2_000
I have a db column for upc codes setup as a 'numeric' data type in postgres.
I generated scaffolding to input values into this table, but rails is converting the input in FLOAT for some reason,
eg, a 13 digit number entry 1234567890000 is converted to 1234567890000.0
from the logs:
INSERT INTO "upc_codes" ("upccode") VALUES (1234567890000.0) RETURNING "id"
Where is the data type for the SQL statement being set, or not set as the case may be?
What data type are using for this column? Try changing the column type to an integer in a migration:
change_column :upc_codes, :upc_code, :integer
max integer value for an mysql integer should be 2147483647 .
i will suppose this could cause an errors somewhere .
try to change the coulm into a bigint .
aniway ,from my experience is better to handle bignum using string in rails (in this manner you could saftly change db). you could always use to_i later in your code .
sorry for my english.
When you set the column type to NUMERIC are you specifying the precision/scale like this: NUMERIC(13,0)? (13 is precision, 0 is scale)
I submitted this again as an answer because I guess I commented when I should have answered.