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

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

问题描述

我目前正在开展一个项目,将我们的一个 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-on-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, ...).

前端,即用户喜欢的任何格式.我这里用法语坚持问题<​​sup>*.

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. Outbound:输出 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

outbound 转换步骤(英语 => 法语)可以通过覆盖 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

inbound 转换步骤(法语 => 英语)将在模型中处理.我们将覆盖 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 的工作原理与我上面概述的相同,但工作更全面:

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

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

但有一个警告:它不处理客户端验证.如果你使用它们,你必须弄清楚如何在你最喜欢的 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天全站免登陆