Task B: Catalog Display #3

Paul asks:

Working in the UK, it would be tiresome to have to pass @{:unit => "£"}@ to most calls I make to number_to_currency. Is there an easy way to set the default to £ and only display '$' if I request it?

Lawrence says:

I think you can write an helper function in store_helper.rb. Something like "number_to_pounds" which calls "number_to_currency" with the right unit.

Niklas asks:

Is there any way put have the unit appear after the the price? Here in Denmark we usually write our prices like "99,95kr" not "kr99,95".

Niklas adds:

Having just looked at the source for number_to_currency, sadly I must conclude that it's not possible.. I will write my own helper method instead, ripping off the source :)

Marko Ž. adds:

You can do this where "before" defines position of unit

def number_to_currency(number, options = {})
  options   = options.stringify_keys
  precision = options["precision"] || 2
  unit      = options["unit"] || " kn"
  separator = precision > 0 ? options["separator"] || "." : ""
  delimiter = options["delimiter"] || ","
  before    = options["before"] || true
     parts = number_with_precision(number, precision).split('.')
     middle = number_with_delimiter(parts[0], delimiter) + separator + parts[1].to_s
     (before == true) ?  middle + unit : unit + middle

Gylve adds:

Marko, for this to work you need to change the line:

 before    = options["before"] || true

 (options.has_key?("before")) ? before = options["before"] : before = true

and the line:
 (before == true) ?  middle + unit : unit + middle

 (before) ? unit + middle : middle + unit

There is a hidden bug, it took me a while to find it. The variable before always will be true, whether you call the number_to_currency method with :before => true or :before => false or without this parameter. And another bug is that the ternary operator has reversed order (you probably accomodated it to return the unit after the price)

Let me explain. The Ruby Hash class returns by default nil if you try to reference non-existent hash key.
And these are the cases that can we have when calling the number_to_currency method:
First: we ommit the optional hash key :before. The before variable will be true, because the default value returned by non-existent hash key will be nil, which is equivalent to false in ruby boolean expressions.
Second: we call it with :before => true. The before variable will be again true.
Third: we call it with :before => false. Guess what? before is again true.

But anyhow thanks for the clue.

Javi adds:

I've added a number_to_currency method to store_helper.rb so it calls ActionView::Helpers::NumberHelper#number_to_currency with different default options. This way the view doesn't have to be changed.

module StoreHelper
  def number_to_currency(number, options= {:unit => "€", :separator => ","})
    Object.new.extend(ActionView::Helpers::NumberHelper).number_to_currency(number, options)

Zach says:

Niklas, you can actually do this with number_to_currency by specifying the format with :format => "%n%u".

Trientalis says:

I am from Europe and like the Euro:
I wrote this helper method in application_helper.rb, so that I can use it in all controllers of this application:

def currency_euro (item)
    number_to_currency (item, :unit => "€", :separator => ",", :delimiter => "", :format => "%n %u")

This works well.

You call this method in the views like this:

<%=currency_euro product.price -%>

product_price reflects the so called "item" in the above helper method. To emphasize that, one could use parenthesis:

<%=currency_euro (product.price) -%>

Haeil says:

I think these are not real solutions.
We need more precise internationalization solution, like Locale in java.
Do you know, an Indian write their number like this : 12,34,56,789. How colud we response all of difference…

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License