Rails国际化:Presenter类下如何保留惰性查找与YAML结构?
在Presenter中兼顾Rails I18n的简洁调用与YAML结构
Rails的I18n惰性查找在视图里用起来很省心——比如在app/views/clients/show.html.erb里写<%= t '.good_client' %>,系统会自动对应en.clients.show.good_client的翻译,不用写全路径。但把视图逻辑抽到Presenter后就尴尬了:要么写冗长的全路径I18n.t('clients.show.good_client'),要么把YAML扁平化破坏结构。下面给几个实用的解决方法:
方法1:给Presenter固定I18n作用域
直接在Presenter里定义对应的I18n命名空间,再封装个自己的t方法,就能像视图里一样简洁调用:
class ClientPresenter # 把对应的I18n作用域写成常量,避免硬编码重复 I18N_SCOPE = 'clients.show'.freeze # 封装自己的翻译方法,自动带上作用域 def t(key, **options) I18n.t(key, scope: I18N_SCOPE, **options) end def good_client t('.good_client') # 等价于I18n.t('clients.show.good_client') end def welcome_note t('.welcome') # 对应en.clients.show.welcome end end
对应的YAML依然保持清晰的层级结构:
en: clients: show: good_client: 5星客户 welcome: 欢迎您的到来!
方法2:复用视图的查找上下文
如果Presenter是和特定视图绑定的,直接把视图的lookup_context传给Presenter,就能完全复用视图的惰性查找逻辑:
在app/views/clients/show.html.erb里初始化Presenter:
<%= ClientPresenter.new(lookup_context).good_client %>
Presenter代码:
class ClientPresenter def initialize(lookup_context) @lookup_context = lookup_context end # 直接用视图的翻译方法,和视图里的写法完全一致 def t(key, **options) @lookup_context.t(key, **options) end def good_client t('.good_client') # 自动对应clients.show命名空间 end end
这种方式完全和视图的惰性查找行为对齐,不用额外配置作用域,YAML结构也丝毫不改。
方法3:借助ActiveModel的翻译模块
如果你的Presenter可以和ActiveModel沾边,直接引入ActiveModel::Translation模块,利用它的作用域推断能力:
class ClientPresenter include ActiveModel::Translation # 指定根作用域为clients def self.i18n_scope :clients end # 封装方法时带上action(比如show) def t(key, action: 'show', **options) I18n.t("#{action}.#{key}", scope: self.class.i18n_scope, **options) end def good_client t('good_client') # 对应en.clients.show.good_client end end
总结
这几种方法都能让你在Presenter里用简洁的方式调用翻译,同时保留YAML的结构化组织。如果Presenter只服务于特定视图,方法2最省心;如果是更通用的Presenter,方法1或3更灵活。
内容的提问来源于stack exchange,提问作者Dan SimBed
相关产品推荐
相关产品推荐

