在Ruby on Rails中本地化包含数字的文本字段

我目前正在开展一个项目,将我们的一个ruby-on-rails网络应用程序国际化,以便它可以在其他国家使用(法国将是这种情况下的第一个)。

我还没有解决的一个特殊问题是显示数字字段。 显示数字仅用于显示目的时,我执行以下操作:

 2)%> 

在英语中,这显示17.50 ,但在法语中它显示17,50 (用逗号代替小数点),这是预期的。 当我显示文本字段时,问题出现在编辑表单中

  15 %> 

当这在屏幕上呈现一个文本框时,文本框始终显示17.50,其中包含句号而不是法语的逗号。 我不确定这是否正确。

当我尝试执行以下操作时:

  15, :value => number_with_precision(f.object.rate, :precision => 2) %> 

这确实在法语文本框中显示了17,50 ,但是当我点击Update按钮保存表单时,Rubyvalidation开始并告诉我17,50不是一个数字(或者更确切地说是“n” ‘est pas un nombre’)。 我必须输入17.50才能保存。

说实话,我不完全确定在这里做正确的事情。 是否所有国家/地区都应在文本框中输入完全停止的数字,或者是否有办法让Ruby-on-Rails显示逗号并对其进行适当validation?

TL; DR

这是我不喜欢一遍又一遍地做的事情(我为法国用户服务,他们很容易将点作为小数点分隔符混淆)。

我现在专门使用delocalize gem ,它会自动为您进行格式转换。 你只需要安装gem并保持你的表格原样,一切都应该照顾你。

我喜欢读书,给我很长的解释

基本转换非常简单,您必须在以下格式之间来回转换:

  • 后端程序,通常是英语,由持久存储使用(SQL数据库,NoSQL存储,YAML,平面文本文件,无论你想要什么,……)。

  • 前端之一,是用户喜欢的任何格式。 我将在这里使用法语来坚持问题*

*也因为我很偏爱它;-)

这意味着您有两点需要进行转换:

  1. 出站 :输出HTML时,您需要将英语转换为法语。

  2. 入站 :处理表单POST的结果时,您需要从法语转换回英语。

手动方式

假设我有以下模型, rate字段为十进制数,精度为2(例如19.60 ):

 class Tax < ActiveRecord::Base # the attr_accessor isn't really necessary here, I just want to show that there's a database field attr_accessor :rate end 

出站转换步骤(英语=>法语)可以通过覆盖text_field_tag来完成:

 ActionView::Helpers::FormTagHelper.class_eval do include ActionView::Helpers::NumberHelper alias original_text_field_tag text_field_tag def text_field_tag(name, value = nil, options = {}) value = options.delete(:value) if options.key?(:value) if value.is_a?(Numeric) value = number_with_delimiter(value) # this method uses the current locale to format our value end original_text_field_tag(name, value, options) end end 

入站转换步骤(法语=>英语)将在模型中处理。 我们将覆盖rate属性writer,用英语分隔符替换每个法语分隔符:

 class Tax < ActiveRecord::Base def rate=(rate) write_attribute(:rate, rate.gsub(I18n.t('number.format.separator'), '.') end end 

这看起来不错,因为示例中只有一个属性和一种要解析的数据类型,但想象一下,必须对模型中的每个数字,日期或时间字段执行此操作。 这不是我的乐趣。

这也是一种天真的*转换方式,它无法处理:

  • 日期
  • 分隔符(例如100,000.84

*我已经告诉过你我喜欢法语吗?

输入delocalize

Delocalize正在按照我上面概述的相同原则工作,但更全面地完成工作:

  • 它处理DateTimeDate Time和数字。
  • 您无需执行任何操作,只需安装gem即可。 它检查您的ActiveRecord列以确定它是否是需要转换的类型并自动执行。
  • 数字转换非常简单,但日期非常有趣。 解析表单的结果时,它将按降序顺序尝试语言环境文件中定义的日期格式,并且应该能够理解格式如下的日期: 15 janvier 2012
  • 每次出站转换都将自动完成。
  • 它已经过测试。
  • 它很活跃。

但有一点需要注意:它不处理客户端validation。 如果你正在使用它们,你将不得不弄清楚如何在你最喜欢的JavaScript框架中使用i18n。

这是gsub技术:

在你的模型中:

 before_validation :prepare_number def prepare_number self.rate.gsub(/,/, '.') if self.rate.match /,\S/ end