change number to number to currency and Human-friendly format - ruby-on-rails

i am trying to convert some digits to currency and human friendly format in ruby on rails.
i know it could be done like this number_to_currency(number_to_human(4000000)) but for some reason im trying to do it like this.
eg. something like this 4000000.to_s(:human).to_s(:currency) => "$4 Million"
it this possible somehow ?

You're looking for number_to_human.
number_to_currency(number_to_human(4000000))

Try to write this code in en.yml as the following:
number:
currency:
format:
delimiter: ! ','
format: ! '%u%n'
precision: 2
separator: .
significant: false
strip_insignificant_zeros: false
unit: $
format:
delimiter: ! ','
precision: 3
separator: .
significant: false
strip_insignificant_zeros: false
human:
decimal_units:
format: ! '%n %u'
units:
billion: Billion
million: Million
quadrillion: Quadrillion
thousand: Thousand
trillion: Trillion
unit: ''
format:
delimiter: ''
precision: 3
significant: true
strip_insignificant_zeros: true
and write the following code:
number_to_currency(number_to_human(4000000))
read about number_to_human from these: link_1, and link_2

Related

How do I prevent ActiveSupport using units, tens, and hundreds localisations in number_to_human?

I've set up a custom locale to get ActiveSupport to use short suffixes when calling number_to_human. Instead of number_to_human(123456) => '123.4 Thousand', it gives me number_to_human(123456) => '123.4k'.
This all works fine. What doesn't work is that while the default locale would leave smaller numbers alone (i.e. number_to_human(56) => 56), my custom locale doesn't. I've left the suffixes for units, tens, and hundreds blank, but this results in number_to_human(52) => '5.2' (i.e. 5.2 tens) or number_to_human(123) => '1.23' (for 1.23 hundreds).
How do I tell ActiveSupport not to use units, tens, or hundreds at all - to just leave numbers under 1000 alone?
Here's the locale file, if it helps (config/locales/en-ABBREV.yml):
en-ABBREV:
datetime:
distance_in_words:
x_seconds: '%{count}s'
x_minutes: '%{count}m'
about_x_hours: '%{count}h'
x_hours: '%{count}h'
x_days: '%{count}d'
x_weeks: '%{count}w'
about_x_months: '%{count}mo'
x_months: '%{count}mo'
x_years: '%{count}y'
number:
human:
unit: ''
ten: ''
hundred: ''
thousand: 'k'
million: 'm'
billion: 'b'
trillion: 't'
quadrillion: 'qd'
And my calls to number_to_human in the view look like this:
number_to_human #posts.count, precision: 1, significant: false, locale: 'en-ABBREV',
units: 'number.human', format: '%n%u'
Looking at the docs of that method I think you can define the unit you want to use like the following. When a key (like tens) is not included in the units then that units will just not be used.
number_to_human(
#posts.count,
format: '%n%u',
precision: 1,
significant: false
units: {
thousand: 'k',
million: 'm',
billion: 'b',
trillion: 't',
quadrillion: 'qd'
}
)

How to convert symbols to strings (i.e. strip leading :) ruby to_yaml

Am trying to remove the leading : from my YAML output. Here is the code and what I have done below:
model/attribution_channel.rb
DEFAULT_BONUS_CONFIG = {
sign_up: {
currency: 'ngn',
type: 'flat',
amount: 1000
},
visit: {
currency: 'ngn',
type: 'flat',
amount: 5
}
}
view/form.slim.html
AttributionChannel::DEFAULT_BONUS_CONFIG.to_yaml
The Output:
To remove the YAML Separator --- and the Leading : in the keys from my output, here is what I have done:
AttributionChannel::DEFAULT_BONUS_CONFIG.to_yaml.gsub("---\n", '').sub(":", '')
..but the .sub(":", '') part removed only the : of the first leading :.
How do I remove the leading : from my YAML output? Any help is appreciated? Here is what I want below:
sign_up:
currency: ngn
type: flat
amount: 1000
visit:
currency: ngn
type: flat
amount: 5
You need to have keys as strings to skip : generation
require 'active_support/core_ext/hash/keys'
require 'yaml'
DEFAULT_BONUS_CONFIG.deep_stringify_keys.to_yaml.gsub("---\n", '')
=> "sign_up:\n currency: ngn\n type: flat\n amount: 1000\nvisit:\n currency: ngn\n type: flat\n amount: 5\n"
You can convert hash keys to strings before generating YAML. The code below goes through a hash recursively convering every key to hash and stringifying every value if it's a hash (note that it's not prepared for circular dependencies in hash).
def stringify(hash)
hash.map{|k, v| [k.to_s, v.is_a?(Hash) ? stringify(v) : v] }.to_h
end
puts stringify(DEFAULT_BONUS_CONFIG).to_yaml
---
sign_up:
currency: ngn
type: flat
amount: 1000
visit:
currency: ngn
type: flat
amount: 5
EDIT: Regarding the --- at the beginning, see this answer.

number_with_precision not giving back correct result for :fr locale in ruby on rails [duplicate]

This question already has answers here:
Rails locale not working
(2 answers)
Closed 7 years ago.
I am using the following to localize a number into french-
number_with_precision(111.234, locale: :fr)
According to the rails documentation it should return-
111,234
as french numbers use a . and , interchangeably as compared to british english.
However i get this response -
111.234
There is no response in the result. I have added :fr locale in a my application.rb -
config.i18n.available_locales = [:en, :fr]
Is there a reason it is not localizing my numbers? any other configuration i am missing out on?
For context i have done this in rails console -
pry(main)> include ActionView::Helpers
=> Object
pry(main)> number_with_precision(111.234, locale: :fr)
=> "111.234"
I was missing a locale file for :fr .
this is what i added in my fr.yml -
fr:
number:
format:
delimiter: ! ','
precision: 2
separator: ','
significant: false
strip_insignificant_zeros: false
Works perfectly well now :)

Will translation work as options for number_to_percentage helper?

I have these 2 different translation options for number_to_percentage:
lt:
percentage:
format:
precision: 2
delimiter: ''
format: "%n%"
strip_insignificant_zeros: false
separator: '.'
and
default:
percentage:
format:
precision: 2
delimiter: ''
format: "%n%"
strip_insignificant_zeros: true
separator: '.'
In case I have LT translations keys I get
number_to_percentage 150.000 => 150.00%
if I remove LT translations keys:
number_to_percentage 150.000 => 150,000%
when expected was:
150%
as I have strip_insignificant_zeros: true in translations.
I am understanding wrong how translations works with helpers? Can translations be used as options for a helper?
Thank you.
application.rb
config.i18n.default_locale = :default
config.i18n.fallbacks = true
Try with this on the .yml file
format: %{n}%
t(:format, :n => 150.000)

Rails shorter "time_ago_in_words"

Is there a different time calculation in rails besides "time_ago_in_words"?? I want to be able to use just 'h' for hours 'd' days 'm' for months... ex. 3d, or 4h, or 5m
My code now...
<%= time_ago_in_words(feed_item.created_at) %> ago.
The components that make up this string can be localised, and are in the datetime.distance_in_words namespace
For example stick
en:
datetime:
distance_in_words:
x_minutes:
one: "1m"
other: "%{count}m"
And rails will say 10m instead of 10 minutes. Repeat as needed for hours, seconds days etc. you can check locales/en.yml in action_view for all the keys.
If you only want the short format you could create a pseudo locale that only used those keys and use it like so
time_ago_in_words created_at, false, :locale => :en_abbrev
In the newer versions of rails, you can specify a scope as an option for the method like so:
time_ago_in_words(company.updated_at, scope: 'datetime.distance_in_words.abbrv')
Then you just need to have your regular i18n file structured like so:
en:
datetime:
distance_in_words:
abbrv:
about_x_hours:
one: ~ 1h
other: ~ %{count}h
about_x_months:
one: ~ 1mo
other: ~ %{count}mo
about_x_years:
one: ~ 1y
other: ~ %{count}y
almost_x_years:
...
This information is also available in the documentation:
https://api.rubyonrails.org/classes/ActionView/Helpers/DateHelper.html#method-i-distance_of_time_in_words
Here's some other ways to do it. You run the method like normal, and then you use gsub on the string.
Chained
string.gsub(/ mi.*/, 'm')
.gsub(/ h.*/, 'h')
.gsub(/ d.*/, 'd')
.gsub(/ mo.*/, 'mo')
.gsub(/ y.*/, 'y')
Hash
string.gsub(/ .+/, {
' minute'=> 'm', ' minutes'=>'m',
' hour' => 'h', ' hours' => 'h',
' day' => 'd', ' days' => 'd',
' month' => 'mo', ' months' => 'mo',
' year' => 'y', ' years' => 'y'
})
Block
string.gsub(/ .+/) { |x| x[/mo/] ? 'mo' : x[1] }
They all do the same except for when the string is "less than a minute". The chained solution returns "less than a minute". The hash solution returns "less". The block solution returns "lesst".
Just change the locale file for this one case
en:
datetime:
distance_in_words:
less_than_x_minutes:
one: '<1m'
Or add a return to clause at the top of your method
def my_method(string)
return '<1m' if string == 'less than a minute'
# code
end
Note: Does not include solutions for include_seconds: true option.

Resources