Ruby Forum Rails I18n > L10n of numbers?

Posted by Isak Hansen (Guest)
on 07.01.2008 15:30
(Received via mailing list)
I need to localize numbers in text fields and have been looking at the
various L10n plugins that claim to have number support. Support seems
to mean that the plugin includes a Number#to_localized_string method,
which isn't very useful for my purposes.

I figure I could build my own numeric_field helper easy enough; the
question is how I'd go about parsing the input before it reaches
Rails.

Currently I'm thinking along the lines of prefixing the field names
with some string, e.g. 'numeric_value_', parsing the (possibly nested)
parameter hash (from a before filter?) looking for these things, and
then adding them back into params as standard English-formatted
numbers without the prefix.

Thoughts/feedback..?


Regards,
Isak
Posted by Benjamin Meichsner (benni)
on 02.07.2008 11:46
Hey Isak,

I currently working on the same problem. In my last projects I have 
workaround with an own setter for the numbers. e.g.

the active-record model
class Article
  def price=(value)
    self.price = value.to_delocalized_decimal
  end
end

and the String-class extension:

class String
  def to_delocalized_decimal
    return self if !self.is_a?(String) or self.blank?
    BigDecimal.new(string.sub(',', '.'))
  end
end

maybe this is usefull for your research-program. But i guess its better 
to use extra methods to fill your database-field. In this case the 
output would be also localized. e.g.

def localized_price=(value)
  self.price = value.to_delocalized_decimal
end
def localized_price
  price.to_delocalized_decimal # use another BigDecimal-extension
end


and the premium-version would be an ActiveRecord::Base-extension. Any 
suggestions how to build such a plugin?

cheerio
benni

Posted by Jarkko Laine (jarkko)
on 02.07.2008 16:39
(Received via mailing list)
On 2.7.2008, at 12.46, Benjamin Meichsner wrote:

> end
> maybe this is usefull for your research-program. But i guess its  
> better
> to use extra methods to fill your database-field. In this case the
> output would be also localized. e.g.
>
> def localized_price=(value)
>  self.price = value.to_delocalized_decimal
> end
> def localized_price
>  price.to_delocalized_decimal # use another BigDecimal-extension
> end

Just curious, but you do realize that to_delocalized_decimal is only
defined in the String class? That has two consequences: any other
object than a string will throw an exception. That's ok, if you only
ever get strings as values. However, in that case (and anyway since
you're defining the method in the String class) there's no idea
checking whether self is a string in the to_delocalized_decimal
method. self.is_a?(String) will always return true when used inside a
method of the String class.

//jarkko

--
Jarkko Laine
http://jlaine.net
http://dotherightthing.com
http://www.railsecommerce.com
http://odesign.fi
Posted by Benjamin Meichsner (benni)
on 02.07.2008 20:00
Hey Jarkko,
thanks for your comment. I give it another try:

# the extensions
class String
  def to_delocalized_decimal
    BigDecimal.new(self.sub(',', '.'))
  rescue
    self
  end
end
class BigDecimal
  def to_localized_string(precision=2)
    ("%01.#{precision}f" % self).to_s.sub('.', ',')
  rescue
    self.to_s
  end
end

# my ActiveRecord-Class
class Article < ActiveRecord::Base
  def localized_price=(value)
    self.price = value.to_delocalized_decimal unless value.blank?
  end
  def localized_price
    price.to_localized_string if price
  end
end

# my new.html.erb
...
<b>Price</b><br />
<%= f.text_field :localized_price %>

But I guess, you have a solution more elegant? I'm dreaming of an 
ActiveRecordPlugin, so I just have to write ..

class Article
  localized_decimal :price, :tax ...
end

... and I got the two setter and getter methods for free. Anyone have an 
idea how to make it?

Greetings
Benni
Posted by Jarkko Laine (jarkko)
on 02.07.2008 21:22
(Received via mailing list)
On 2.7.2008, at 21.00, Benjamin Meichsner wrote:

> end
>  def localized_price=(value)
> <%= f.text_field :localized_price %>
>
> But I guess, you have a solution more elegant? I'm dreaming of an
> ActiveRecordPlugin, so I just have to write ..

Sorry, I've just used a before_save filter defined in AR::Base. It
would be fairly easy to make a plugin out of that, all it takes is
some metaprogramming skills. If you aren't familiar with
metaprogramming in Ruby, I highly recommend PragDave's recent
screencasts 
(http://www.pragprog.com/screencasts/v-dtrubyom/the-ruby-object-model-and-metaprogramming
). They'll cost you $5 a piece, but with the current state of the
dollar that's not too much asked imho.

Cheers,
//jarkko

--
Jarkko Laine
http://jlaine.net
http://dotherightthing.com
http://www.railsecommerce.com
http://odesign.fi