LoginSignup
6
2

More than 3 years have passed since last update.

【Rails】I18n.tはtに省略できるんじゃない、省略したほうが良い

Posted at

I18n.tの省略記法

まだなんにもわかっていないRails触り始めて1週間くらいの頃、
「RailsはViewファイル内ではI18n.t('hoge')って書かなくてもt('hoge')って書けるよ、
先輩たちもそう書いてるから合わせてね」
って言われてふむふむなるほど、
よくわからんがviewでは省略できるのかってなった経験はありませんか?

実はI18n.tをtにすると文字が4文字節約できるってレベルではない変化が起きていた

つまりどういう事か

詳しい実相はこの辺
TranslationHelperにtが実装されていたんですね

rails/actionview/lib/action_view/helpers/translation_helper.rb
def translate(key, options = {})
  options = options.dup
  if options.has_key?(:default)
    remaining_defaults = Array.wrap(options.delete(:default)).compact
    options[:default] = remaining_defaults unless remaining_defaults.first.kind_of?(Symbol)
  end

  # If the user has explicitly decided to NOT raise errors, pass that option to I18n.
  # Otherwise, tell I18n to raise an exception, which we rescue further in this method.
  # Note: `raise_error` refers to us re-raising the error in this method. I18n is forced to raise by default.
  if options[:raise] == false
    raise_error = false
    i18n_raise = false
  else
    raise_error = options[:raise] || ActionView::Base.raise_on_missing_translations
    i18n_raise = true
  end

  if html_safe_translation_key?(key)
    html_safe_options = options.dup
    options.except(*I18n::RESERVED_KEYS).each do |name, value|
      unless name == :count && value.is_a?(Numeric)
        html_safe_options[name] = ERB::Util.html_escape(value.to_s)
      end
    end
    translation = I18n.translate(scope_key_by_partial(key), **html_safe_options.merge(raise: i18n_raise))
    if translation.respond_to?(:map)
      translation.map { |element| element.respond_to?(:html_safe) ? element.html_safe : element }
    else
      translation.respond_to?(:html_safe) ? translation.html_safe : translation
    end
  else
    I18n.translate(scope_key_by_partial(key), **options.merge(raise: i18n_raise))
  end
rescue I18n::MissingTranslationData => e
  if remaining_defaults.present?
    translate remaining_defaults.shift, options.merge(default: remaining_defaults)
  else
    raise e if raise_error

    keys = I18n.normalize_keys(e.locale, e.key, e.options[:scope])
    title = +"translation missing: #{keys.join('.')}"

    interpolations = options.except(:default, :scope)
    if interpolations.any?
      title << ", " << interpolations.map { |k, v| "#{k}: #{ERB::Util.html_escape(v)}" }.join(", ")
    end

    return title unless ActionView::Base.debug_missing_translation

    content_tag("span", keys.last.to_s.titleize, class: "translation_missing", title: title)
  end
end
alias :t :translate

ずいぶん色々やってますね

ざっくりいうとI18n.tに引数を渡す前に該当するロケールが存在しなかった場合の保険とか、
挙動にまつわるオプションの分岐とかががっつり書かれているわけですね

というわけで今後I18n.tってviewに書くプルリクエストが来たら修正してもらいましょう

6
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2