I have a field -
:Revenue
and it should accept values like 10,000.00, but if I input such value it stores 10 into database instead of 10000.00
What should I do to strip of commas before I save?
I've tried to find a few solutions online but wasn't able to implement them as I found them incomplete. If someone could help me I would really appreciate it.
**The problem now I am facing is that as soon as I enter the value rails converts string in to float value before it can run the gsub function, like if I enter 50,000.00 its converting into float 50.0 before calling the gsub, is there any way to over the to_f method which rails is calling on the string.
Removing commas is pretty simple:
value.gsub(/,/, '').to_f
Keep in mind that European formatting often uses comma as the decimal value separator so your results would be off by a factor of 100 if processing those sorts of numbers.
You can take a String#delete.
"10,000,000.00".delete(',').to_f
# => 10000000.0
I found the solution after looking at few places and combining few solutions, since I had to use gsub before the linking to model has to be done. so I created the method in my controller and called it before create and update action. and wrote the following code in the method
params[:record][:Revenue] = params[:record][:Revenue].gsub(/,/,"")
Related
I have a model that has an attribute named value this is saved in the db as an integer.
I input the number in the view using a text_field, I am also performing a method on it :before_save that takes the value (something like 21.37) and using the money gem convert it to just cents.
However, it seems that before I can even perform the method that converts it from a float to an integer it is being converted to some kind of integer and the decimal is being lost.
I have tested this by outputting value in the method that runs before_save: and it round it to 21
Does anyone know why this might be happening, Im not performing any other changes to it.
I'm guessing you're doing something like Coupon.new(params) in your controller, and since Rails knows Coupon's value should be an integer, it helpfully calls to_i on params[:value] for you under the covers, which turns 21.37 into 21. Here's a rather inelegant but effective fix:
params[:value] ~= /.*\.(\d+)/
params[:value] = params[:value].to_f * (10**$1.length) if $1
Do that before you do Coupon.new(params).
Another option is to simply assume you don't care about anything after the 2nd decimal place (you're dealing with cents after all). Then you can simply do params[:value] = params[:value].to_f.round(2) * 100.
Also you should consider using number_field instead of text_field in your view so you can at least be sure you're getting a number. Something like number_field(:coupon, :value, step: 0.01) should ensure your users can enter decimals.
I agree with #kitkat seems like something that would happen in the model layer. You might be able to implement your conversion to cents logic in 'before_validation' or perhaps a custom setter for 'coupon'.
In my application I have several price fields. In the model they are of type float and when I want to display them, I use the number_to_currency method provided by NumberHelper and this works fine. However, the input in the form is a problem. Here in The Netherlands, the divider for decimal amounts is a comma, but some people use a dot. Currently, only a decimal amount with a dot gets saved properly. When a decimal is used, only the whole amount gets saved.
So I probably need a before_save sanitizer which replaces a comma with a dot. But I need this for several models. What is the best way to do this?
As the api documentation describes the method number_to_currency has the option :separator you may use.
number_to_currency("1234567890,50", unit: "£", separator: ",", delimiter: "")
Maybe you can set the locale and get the same result.
I have that problem in Germany, too.
I've been using the delocalize gem to perform the "reverse localization", although it still has some problems with Rails 4. (It works, though)
PS: Don't use floating point types for representing currency, you'll get rounding problems. Use BigDecimal instead.
I'm having a problem with localization. In Brazil, we use comma as a decimal separator, instead of dot. For example:
500,00
120,21
0,0001
I found the solution to this problem based on this answer: MVC 3 jQuery Validation/globalizing of number/decimal field
But here in Brazil, we also use "." in numbers, like:
100.000.000,00
11.125,23
And one more thing:
10.000 <> 10,000
The first one is ten thousand, and the second is simply ten.
Using the globalization plugin, when the user types the ".", it shows an validation error.
I tried using the data annotation DisplayFormat, but it didn't work as expected...
To "solve" this problems I'm using javascript to manually set and remove the "." from the numbers on the field, but this is very problematic when we need to change anything (and I'm sure this is one of the worst approaches I could use...). Do you guys have any idea of how to proceed in this case?
One more question: I can create a model binder (or modify the existing one) to accept this number format?
I just found this answer.
Fixing binding to decimals
It worked perfectly in my scenario. This guy solved the exactly same problem I was having!
I just had modify a few lines of code, but the most important part was this line:
ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());
I modified it to accept nullable values.
Why do my decimal value rows are values such as #> instead of just a regular decimal number?
I have a cost column and I get weird values. Is that ok? If so why?
That's just how Ruby prints out BigDecimal objects by default. Not sure why they chose such an ugly format, but hey - maybe some of the extra information can be useful.
Anyway, you should still be able to use them as you expect - it's just a bit of display weirdness. If you want to print a BigDecimal in a more normal format, call to_s on it first, or use puts, which calls to_s for you.
Hope that helps!
Rails automatically casts the "row" decimal value into the Ruby object that it most resembles. In this case, a BigDecimal.
To print it out in a nice way, you can use "to_s" eg:
puts my_decimal.to_s
=> "3000000000000000000.0"
which should print it out nicer than the ugly class-named version you are seeing now.
I need to be able add days or hours to a previously created Item.
The system can add or subtract a set number of hours or days based on attributes stored in the db, :operator (add/subtract), :unit_of_time(hours/days), and :number.
I'd like to be able to do something like:
Date.today+2.days
where "+" is the :operator, "2" is the :number, and "days" is the :unit_of_time but I'm unsure of how to get the interpolated string of attributes to become the actual operator "+2.days". Any ideas?
(I've poured through the ruby documentation, but to no avail. Currently, I'm just manually creating of the possible options (4) in nested if/else blocks... yeah it's gross.)
You could use eval, e.g.:
eval("Date.today+2.days")
...and then simply use string interpolation to put in the variables. Note, however, that you should only do this if you can be very certain that the values in your database are always what you want them to be; under no circumstances should users be able to change them, otherwise you'll have a major security issue which compromises your entire system.
Using more lengthy methods like the if statement you suggested (or a case statement) require you to write more code, but they are much more secure.
All ruby objects have a send method which can be used to run a method by name with parameters. Using send as well as converting strings to ints (.to_i) should suffice.
Date.today.send '+', '1'.to_i.send('months') # This works
Date.today.send operator, number.to_i.send(unit) # Generalized form
Ruby is beautiful!