在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,平面文本文件,无论你想要什么,……)。
-
前端之一,是用户喜欢的任何格式。 我将在这里使用法语来坚持问题* 。
*也因为我很偏爱它;-)
这意味着您有两点需要进行转换:
-
出站 :输出HTML时,您需要将英语转换为法语。
-
入站 :处理表单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正在按照我上面概述的相同原则工作,但更全面地完成工作:
- 它处理
Date
,Time
,Date
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