Remove , from all integers in rails - ruby-on-rails

All integers are by default delimited by ',' .
For ex: 123456 is shown as 1,23,456.
Is there a way to remove ',' from all integers for all tables.
If it is for a single table and a particular field, we can do in the following way in its controller.
config.columns[:<int_field>].options={:i18n_options => {delimiter: ""}}
Is there a way to do this for all integer fields?
PS: Using Activescaffolding in my application.
Thanks.

Use tr as:-
2.0.0-p645 :005 > "1,23,456".tr(',', '')
=> "123456"
Convert the result to integer as:-
2.0.0-p645 :005 > "1,23,456".tr(',', '').to_i
=> 123456
Check methods in string in irb as:-
"".methods
Use it in view as:-
<%= "1,23,456".tr(',', '').to_i %>
For more details see the document

I assume Rails with Activescaffold uses formatting rules from its I18n module by default. You can change them in config/locales/en-US.yml. Here is the default one with the relevant lines highlighted.
This should affect all formatting of numbers in views. I think you just have to change the delimiter to a blank string:
...
format:
delimiter: ""
...
You can find general information about Rails I18n in the corresponding I18n guide.

This worked perfectly.
Added the following lines in application_helper.rb:
def format_number_value(value, delimiter = '')
if value.is_a? Integer
ActiveSupport::NumberHelper.number_to_delimited(value, delimiter: '')
else
super
end
end
Thanks.

Related

How do I change the separator in parameterize for Rails

This seems like a dumb question, but how do I use parameterize in Rails? I've seen this doc: http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-parameterize
In my Model I can get string.parameterize to work, but I don't understand how to use the separator param. parameterize(string, separator: '') says I can't use parameterize on main, and string.parameterize(separator: '') says can't implicitly convert from Hash to String
string.parameterize without specifying any character will give you your string separated by words, removing any character that's not a letter, and "joining" them with '-':
string = 'Donald E. Knuth'
string.parameterize
# => "donald-e-knuth"
This way specifying a separator:
string.parameterize(separator: '*')
# => donald*e*knuth
The method acts using the I18n.transliterate method to the passed string, and then applying a destructive gsub! which will check any non-letter character and apply the substitution, is like to do:
# without separator specified
I18n.transliterate(string).gsub!(/[^a-z0-9\-_]+/i, 'separator')
# => Donald-E-Knuth
So this way if there's no separator specified, the method has one already defined as its third parameter:
def parameterize(string, sep = :unused, separator: '-', preserve_case: false)
...
end
Note the use is first the string and then the parameterize method call, unlike what the documentation exemplifies.
Note: Tested on ruby 2.3.1 and Rails 5.0.2 it works well, Rails 4.2.5, 4.2.6 (as you say) and 4.2.7 throws this error:
Loading development environment (Rails 4.2.5)
> string = 'x y z'
# => "x y z"
> string.parameterize(separator: '*')
TypeError: no implicit conversion of Hash into String
In Rails < 5 it must be used as ActiveSupport::Inflector.parameterize(string, separator):
> #item = Item.first
# => #<Item id: 1, name: "new item" ...>
> ActiveSupport::Inflector.parameterize(#item.name, '*')
# => "new*item"
Take a look at this for more info:
parameterize("Donald E. Knuth", separator: '_') # => "donald_e_knuth"
parameterize("^très|Jolie__ ", separator: '_') # => "tres_jolie"
This method comes from the ActiveSupport::Inflector class, so you can do:
ActiveSupport::Inflector.parameterize("Hello World Yeah!", separator: "*")
# => "Hello*World*Yeah!"

How to resolve this error erb is throwing when passing a currency formatted string

I'm using a module within my Rails App to perform some actions and render a html file and save it to S3. So far so good, apart from the fact that I need to pass a currency variable to to be rendered and erb is throwing this error:
undefined method `/' for "3,395,000":String
Here's my code:
options = {
...
price: Money.new(#case.cash_price / 100.to_i, "DKK").format.to_s.html_safe,
...
}
And here's my module:
def generate_html(options)
require 'erb'
erb_file = "templates/banners/widesky.html.erb"
erb_str = File.read(erb_file)
...
#price = options[:price]
...
renderer = ERB.new(erb_str)
result = renderer.result(binding)
FileUtils.mkdir_p('temp') unless File.directory?('temp')
File.open('temp/index.html', 'w') do |f|
f.write(result)
end
'temp/index.html'
end
And I tried formatting the currency in different ways, but I always get the same error. Any ideas why?
EDIT
#case.cash_price originally is an Integer. I want to convert it to a string with commas (hence using Money to format it). The problem seems to be that erb doesn't like the formatted result and throw the above error.
If for some reason you cannot use any gem/helper, let's reinvent the wheel!
def to_currency(price_in_cents, currency=nil, decimal_separator = '.', thousand_separator = ',')
price_in_cents.to_s.rjust(3,'0').reverse.insert(2,decimal_separator).gsub(/(\d{3})(?=\d)/, '\1'+thousand_separator).reverse+(currency ? " #{currency}" : '')
end
puts to_currency(123456789, 'DKK')
puts to_currency(123456, '€', ',', ' ')
puts to_currency(1)
It outputs :
1,234,567.89 DKK
1 234,56 €
0.01
Note that price_in_cents should be either a String that looks like an Integer ("123456789") or an Integer (123456789), but not a preformatted String ("123,456.78") or a Float (1.23).
Finally, the resulting String is as unsafe as price_in_cents :
to_currency("unsafe_codejs")
=> "unsafe_code.js"
You don't have to specify html_safe on the result anyway, because nothing would be escaped in "1,234,567.89 DKK".
Original answer :
If cash_price is a String with commas, you need to remove the commas first, then convert it to a float, then divide by 100, and then convert the result to an Integer.
cash_price.to_s is to avoid getting errors if cash_price does come as a Numeric.
price: Money.new((#case.cash_price.to_s.delete(',').to_f/100).to_i, "DKK").format.to_s.html_safe
#case.cash_price is a string so you can't perform any mathematical operations on it. You would need to convert the value to an integer (3395000) rather than a comma delimited string as you currently have ('3,395,000').
A side note, 100.to_i is redundant as 100 is already an integer, unless you wanted to convert the equation to an integer, which would need brackets (#case.cash_price / 100).to_i.

How can I write quoted values in en.yml?

I'm writing a script that will add new translations to the en.yml file. However, when I'm dumping them back to the file, my strings are in the following format:
some_key: This is the value
I'm trying to make the output be:
some_key: "This is the value"
I'm writing the translations like this:
File.open(yaml_file, "w") do |f|
f.write(translations.to_yaml)
end
Where translations is the hash containing all the translations.
Is there any way of adding these quotes, besides manually parsing/rewriting the YAML file?
The plan (unquotes) scalar representation is the preferred version when the scalar type doesn't require escaping.
In your case, the String:
This is the value
doesn't need to be in quotes, thus, if you supply the following YAML:
key: "This is the value"
the processor may return:
key: This is the value
because they are totally equivalent. However, if you actually want to enter a quoted string as value, then you should use:
key: '"This is the value"'
or escape the double quote:
key: "\"This is the value\""
I gave a quick look at the Psych emitter code, the one invoked by the to_yaml, and there doesn't seem to be an option to force quoting on scalar.
I don't even see the option implemented in the scalar emitter code.
def visit_Psych_Nodes_Scalar o
#handler.scalar o.value, o.anchor, o.tag, o.plain, o.quoted, o.style
end
In other words, you cannot enforce quoting.
Updated for hash conversion
def value_stringify(hash)
hash.each do |k,v|
if v.kind_of? Hash
hash[k]= value_stringify(v)
else
hash[k]="\"#{v}\""
end
end
end
Now use the converted hash to store yaml.
File.open(yaml_file, "w") do |f|
f.write(value_stringify(translations).to_yaml)
end
Now it should work..
The format you get is valid YAML. However, if you really want this you could temporarily modify your data before converting it.
Normal:
{ foo: "bar" }.to_yaml
# => foo: bar
With an space after:
{ foo: "bar " }.to_yaml
# => foo: 'bar '
Note that you get single quotes and not double quotes. So if you temporarily modifying your data you could add in an placeholder which you remove later.
Example:
{ foo: "foo --REMOVE-- ", bar: "bar --REMOVE-- " }.to_yaml
.gsub(' --REMOVE-- ', '')
# => foo: 'foo'
# bar: 'bar'

How to remove "$" and "," from a price field in Rails

I am saving a price string to my database in a decimal-type column.
The price comes in like this "$ 123.99" which is fine because I wrote a bit of code to remove the "$ ".
However, I forgot that the price may include a comma, so "$ 1,234.99" breaks my code. How can I also remove the comma?
This is my code to remove dollar sign and space:
def price=(price_str)
write_attribute(:price, price_str.sub("$ ", ""))
# possible code to remove comma also?
end
You can get there two ways easily.
String's delete method is good for removing all occurrences of the target strings:
'$ 1.23'.delete('$ ,') # => "1.23"
'$ 123,456.00'.delete('$ ,') # => "123456.00"
Or, use String's tr method:
'$ 1.23'.tr('$, ', '') # => "1.23"
'$ 123,456.00'.tr('$ ,', '') # => "123456.00"
tr takes a string of characters to search for, and a string of characters used to replace them. Consider it a chain of gsub methods, one for each character.
BUT WAIT! THERE'S MORE! If the replacement string is empty, all characters in the search string will be removed.

how to replace an apostrophe using gsub

I want to replace apostrophe(') in a name with "backslash apostrophe" (\') . But Unfortunately not getting such a simple thing.
So on irb I tried following
x = "stack's"
x.gsub(/[\']/,"\'")
Some how it is not working I am getting same result- stack's in place of stack\'s
Try this:
x = "anupam's"; puts x.gsub("'", "\\\\'")
Try this out:
x.gsub(/[']/,"\\\\\'")
Result:
1.9.3p0 :014 > puts x.gsub(/[']/,"\\\\\'")
anupam\'s
Here's a ruby variant for PHPs addslashes method (from http://www.ruby-forum.com/topic/113067#263640). This method also escapes \ in the string, with double \:
class String
def addslashes
self.gsub(/['"\\\x0]/,'\\\\\0')
end
end
Which would correctly escape anupam's:
"anupam's".addslashes # => "anupam\\'s"

Resources