【问题标题】:Rails 5 - Problem with Umlaute and parameterize methodRails 5 - 变音符号和参数化方法的问题
【发布时间】:2020-08-27 04:53:33
【问题描述】:

我在 Rails 5.2.3 和 Ruby 2.5.1 上工作。在某些时候,当我期望我的字符串数组常量包含一些字符串但它没有时,我发现了一个问题。原来问题与德语变音符号(öäü)有关。

所以我有如下定义的常量:

# coding: utf-8
# frozen_string_literal: true
class MyClass
  module MyModule
    MY_CONSTANT = [
      'Breite in mm',
      'Höhe in mm',
      'Länge in mm'
    ].map(&:parameterize).freeze
  end
end

我希望常量看起来像 ["breite-in-mm", "hoehe-in-mm", "laenge-in-mm"]

但它被存储为["breite-in-mm", "hohe-in-mm", "lange-in-mm"]。你看,“ö”已被转换为“o”而不是“oe”。 “ä”也一样。现在是“a”,而不是“ae”。

它在生产、RSpec 测试中甚至在我启动 Rails 控制台并调用此常量时都以这种方式工作。但是,当我使用相同的代码从 Rails 控制台定义一个新常量时,字符串已成功转换为我所期望的,即["breite-in-mm", "hoehe-in-mm", "laenge-in-mm"]

我可以轻松摆脱这个parameterize 方法,只需在需要时输入字符串。也许我将不得不这样做。但我真的很好奇为什么会发生这一切,我自己也找不到答案。

所以提前感谢您的任何想法。

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-5


    【解决方案1】:

    Rails 中的parameterize 方法(通过使用ActiveSupport::Inflector#transliterate)是区域感知的。因此,它使用依赖于区域设置的规则将字符(例如元音变音)音译为 ASCII 字符。

    当您的应用处理请求时(或至少在启动后处理一次),您通常会设置 I18n 语言环境,例如I18n.locale = :de 用于单个请求,I18n.default_locale = :de 用于整个应用程序。之后,Rails(即 i18n gem)默认使用此语言环境作为其音译规则。

    最初设置常量时,可能尚未设置此默认语言环境。因此,i18n gem 不知道德语音译规则,只使用基本的 Unicode 规范化规则。

    作为一种解决方法,您可以将所需的语言环境作为参数传递给参数化方法使用

    MY_CONSTANT = [
      'Breite in mm',
      'Höhe in mm',
      'Länge in mm'
    ].map { |const| const.parameterize(locale: :de).freeze }.freeze
    

    或者您也可以在代码执行之前设置默认的 i18n 语言环境(例如,在 config/initializers 的文件中,具体取决于您初始化常量的确切位置):

    I18n.default_locale = :de
    

    【讨论】:

    • 这太棒了,谢谢!这是我的一个赞成票。不幸的是,这只适用于 Rails 6,所以我为 Rails 5 添加了答案。
    【解决方案2】:

    感谢 Holger,感谢您的出色回答。它似乎是正确的,只是它仅适用于 Rails 6.0.0。因此,我将发布我在项目中使用的 Rails 5.2.3 版本。

    不幸的是,Rails 5 中的 parameterize 方法还不接受 locale 参数。这只能在 Rails 6 中实现。

    但是,正如 Holger Just 的回答中提到的,parameterize 方法依赖于 transliterate 方法,该方法确实使用当前语言环境并根据它转换字符串。

    有关这些方法,请参阅 Rails 5.2.3 文档和来源: https://api.rubyonrails.org/v5.2.3/classes/ActiveSupport/Inflector.html#method-i-parameterize https://api.rubyonrails.org/v5.2.3/classes/ActiveSupport/Inflector.html#method-i-transliterate

    所以我不能直接将语言环境传递给parameterize 方法。然后我应该在定义常量之前设置语言环境。

    application.rb 文件中设置I18n.default_locale = :de 没有帮助。我已经有了,不管怎样,字符串都被音译了。

    最终的帮助是手动设置I18n.locale = :de。多亏了这一点,我正确地参数化了我的字符串,而没有对 MyConstant 定义进行任何更改。

    【讨论】:

      猜你喜欢
      • 2016-05-03
      • 2018-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多