【问题标题】:Use different translations for same ActiveModel class in different contexts?在不同的上下文中对同一个 ActiveModel 类使用不同的翻译?
【发布时间】:2015-11-12 16:23:59
【问题描述】:

我知道这样做是一种轻微的反模式,但有时它只是一个比实现不同的逻辑类或全功能的装饰器/表单对象更容易的解决方案,只是一点点差异。

假设我有一个用户类 (ActiveModel),并且我想在多个不同的上下文中使用它,比如注册和登录。 对于注册,我希望能够有与登录不同的翻译,例如能够为无效的电子邮件格式提供不同的消息。

有没有简单的方法来完成这个?同时能够在同一类对象上工作。因此,SignUp 和 Login 都应该在 FULL User 类上运行,允许使用其中提供的逻辑。

理想情况下,只需获取实例并在实例上设置变量以更改 i18n-tree 的“model_name”部分。

我尝试了几种方法:

代表团

class Login < DelegateClass(User)
end

非常适合在实例级别简单地覆盖/添加逻辑。不幸的是,所有 Rails i18n 的东西都在类级别上运行,没有办法进入,因为 self 反映的是用户而不是登录,也没有真正的登录类来附加逻辑。

装饰

这将是完美世界中的理想解决方案,例如使用表单对象(改革等),但它不可能使用用户逻辑(例如验证)而不费力,复制甚至重新实现它们复杂的案例(例如检查电子邮件的唯一性等)。只是简单的翻译文本更改的开销太大。 另外,这通常带有全套自己的翻译等,除非真的需要,否则我不想复制所有这些 - 也许只需更改一些默认的。

继承

仅对于初始情况(允许更改翻译以进行验证)完美:

class LoginController < ApplicationController
  ...
  class User < ::User
  end
end

这个小魔法在 I18n 回退的前面增加了另一层,所以突然在树中的“用户”之前查找了一个“登录控制器/用户”。 不幸的是,您对具有不同类的对象进行了任何其他操作,因此在执行此操作时必须非常小心,这会产生一些意想不到的副作用。

有没有更好的解决方案?正如我所说,我知道最完美的做法是甚至不直接对 ActiveModel 对象进行操作,但有时引入业务逻辑对象来处理所有事情是完全矫枉过正的 - 并一次又一次地重复大量逻辑。

【问题讨论】:

    标签: ruby-on-rails ruby rails-i18n


    【解决方案1】:

    处理翻译的最佳方式是使用内置的 I18n 库。 http://guides.rubyonrails.org/i18n.html

    这样您可以设置:sign_in_text 或:email_format_error 的键,并根据所选的语言环境动态替换它。

    您可以像下面一样使用它,在上面的链接中添加一些额外的设置细节。

    # config/locales.en.yml
    en:
      home:
        index:
          sign_in_header: "Sign Up Here!"
    

    在视图中

    # app/views/home/index.html.erb
    <h1><%= t :sign_in_header %></h1>
    

    【讨论】:

    • 这适用于视图级翻译,但不适用于来自模型的任何内容,例如模型/属性名称或验证错误消息。当然,我可以在登录视图的范围内重新定义像“email_format_error”这样的消息,但是当显示每条消息时,我需要在视图中添加大量逻辑。
    • 错误应该根据区域设置正确转换。见:guides.rubyonrails.org/…。还有一些关于覆盖这些消息的默认值的信息
    • 这仅适用于一个翻译案例,但我希望能够使用不同的集合,甚至每个案例的翻译继承。我确实非常了解 rails i18n 的工作原理,但我没有找到令人满意的方法来解决这个额外的要求。
    猜你喜欢
    • 1970-01-01
    • 2023-02-02
    • 2012-03-11
    • 2017-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多