在不同的上下文中为同一个ActiveModel类使用不同的翻译?

时间:2015-11-12 16:24:00

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

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

鉴于我有一个User类(ActiveModel),我想在多个不同的上下文中使用它,比如说SignUp和Login。 对于SignUp,我希望能够拥有与登录不同的翻译,例如能够为无效的电子邮件格式提供不同的消息。

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

理想情况下,只需在实例上设置实例并设置变量即可更改' model_name' i18n-tree的一部分。

我试过几种方法:

class Login < DelegateClass(User)
end

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

装饰

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

继承

仅针对初始案例(允许更改验证的翻译)完美:

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

这一小块魔法在I18n后备的前面添加了另一层,因此突然出现了一个&login -controller / user&#39;在用户&#39;之前查找在树上。 不幸的是,你使用不同的类对对象进行任何其他操作,因此在执行此操作时必须非常小心,这会产生一些意想不到的副作用。

那里有更好的解决方案吗?正如我所说的,我知道完美的一个就是不能直接对ActiveModel对象进行操作,但有时它只是完全过度杀戮来引入业务逻辑对象来处理所有事情 - 并且一次又一次地复制大量逻辑。 / p>

1 个答案:

答案 0 :(得分:0)

处理翻译的最佳方法是使用内置的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>