在Ruby on Rails中本地化包含数字的文本字段 [英] Localizing a text field containing a number in Ruby on Rails

查看:74
本文介绍了在Ruby on Rails中本地化包含数字的文本字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在开展一个项目,以使我们的红宝石Web应用程序国际化,以便可以在其他国家/地区使用(在这种情况下,法国将是第一个).

I am currently working on a project to internationalize one of our ruby-on-rails web applications so that it can be used in other countries (France will be the first one in this case).

我尚未解决的一个特定问题是数字字段的显示.当仅出于显示目的而显示数字时,我将执行以下操作:

A particular issue I haven't worked out yet is with the displaying of numeric fields. When displaying numbers for display purposes only, I do the following:

<%= number_to_percentage(tax.rate, :precision => 2)%>

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

In English, this shows 17.50, but in French it shows 17,50 (with a comma in place of the decimal point) which is as expected. The problem comes in the Edit form, when I show a text field

<%= f.text_field :rate, :size => 15 %>

这会在屏幕上呈现文本框时,该文本框始终显示带句号的 17.50 而不是法文的逗号.我不确定那是正确的.

When this renders a text box on the screen, the text box always shows 17.50 with a full stop rather than a comma for French. I am not sure that is correct.

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

When I tried doing the following:

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

这确实在法语文本框中显示了 17,50 ,但是当我单击更新"按钮以保存表单时,Ruby验证就会启动并告诉我 17 ,50 不是数字(或者说"n'est pas un nombre").我必须输入 17.50 才能保存.

This did indeed show 17,50 in the text box for French, but when I click on the Update button to save the form, the Ruby validation kicks in and tells me that 17,50 is not a number (or rather it says "n'est pas un nombre"). I have to enter 17.50 to get it to save.

说实话,我不确定在这里做正确的事.应该所有国家/地区在文本框中输入带句号的数字,还是有办法让Ruby-Rails显示逗号并进行适当验证?

To be honest, I am not entirely sure on the correct thing to do here. Should all countries enter numbers with full stops in text boxes, or is there a way to get Ruby-on-Rails to display commas, and validate them appropriately?

推荐答案

TL; DR

这是我讨厌一遍又一遍地做的事情(我为法国用户提供服务,他们很容易将点作为小数点分隔符引起混淆).

TL;DR

This is the kind of things I hate to do over and over again (I'm serving french users, they're easily confused with dots as the decimal separator).

我现在专门使用 delocalize gem ,它会自动为您进行格式转换.您只需要安装gem并保持原样,就应该为您做好一切准备.

I exclusively use the delocalize gem now, which does the format translation automatically for you. You just have to install the gem and leave your forms as-is, everything should be taken care of for you.

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

The basic conversion is quite simple, you have to convert back and forth between the following formats:

  • 持久性存储(SQL数据库,NoSQL存储,YAML,纯文本文件,不管您喜欢什么,...)使用的后端通常是英语.

  • The backend one, which is usually English, used by your persistent storage (SQL database, NoSQL store, YAML, flat text file, whatever struck your fancy, ...).

前端,它是用户喜欢的任何格式.我将在这里使用法语回答问题 * .

The frontend one, which is whatever format your user prefers. I'm going to use French here to stick to the question*.

*也是因为我对此很偏爱;-)

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

This means that you have two points where you need to do a conversion:

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

  1. Outbound: when outputting your HTML, you will need to convert from English to French.

入站:处理POST形式的结果时,您需要将法语转换回英语.

Inbound: When processing the result of the form POST, you will need to convert back from French to English.

手动方式

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

The manual way

Let's say I have the following model, with the rate field as a decimal number with a precision of 2 (eg. 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来完成:

The outbound conversion step (English => French) can be done by overriding 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属性编写器,以将每个法语分隔符替换为英文分隔符:

The inbound conversion step (French => English) will be handled in the model. We will override the rate attribute writer to replace every French separator with the English one:

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

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

This look nice because there's only one attribute in the example and one type of data to parse, but imagine having to do this for every number, date or time field in your model. That's not my idea of fun.

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

This also is a naïve* way of doing the conversions, it does not handle:

  • 日期
  • 时报
  • 定界符(例如100,000.84)

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

取消本地化的工作原理与我上面概述的相同,但工作范围更为广泛:

Delocalize is working on the same principle I outlined above, but does the job much more comprehensively:

  • 它处理DateTimeDateTime和数字.
  • 您无需执行任何操作,只需安装gem.它会检查您的ActiveRecord列,以确定它是否是需要转换并自动进行转换的类型.
  • 数字转换非常简单,但是日期转换确实很有趣.解析表单结果时,它将尝试按降序尝试在区域设置文件中定义的日期格式,并且应该能够理解这样的日期格式:15 janvier 2012.
  • 每个出站转换都将自动完成.
  • 已经过测试.
  • 它是活动的.
  • It handles Date, Time, DateTime and numbers.
  • You don't have to do anything, just install the gem. It checks your ActiveRecord columns to determine if it's a type that needs conversion and does it automatically.
  • The number conversions are pretty straightforward, but the date ones are really interesting. When parsing the result of a form, it will try the date formats defined in your locale file in descending order and should be able to understand a date formatted like this: 15 janvier 2012.
  • Every outbound conversion will be done automatically.
  • It's tested.
  • It's active.

一个警告:它不处理客户端验证.如果要使用它们,则必须弄清楚如何在自己喜欢的JavaScript框架中使用i18n.

One caveat though: it doesn't handle client-side validations. If you're using them, you will have to figure out how to use i18n in your favourite JavaScript framework.

这篇关于在Ruby on Rails中本地化包含数字的文本字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆