LoginSignup
41
32

More than 5 years have passed since last update.

Railsのi18nのYAMLファイル(ja.yml)をリファクタリングする

Posted at

config/locales/*.ymlが長すぎて編集しづらい

Railsのja.ymlは長くなってインデントを間違ったり、重複が混ざっちゃったりと管理しづらいYAMLファイルになりがちですよね。

以下例のように各エントリーが参照のみで構成されていれば分かりやすいのに。

ja:
  devise: *devise
  errors: *errors
  helpers: *helpers
  number: *number
  support: *support
  time: *time
  date: *date
  datetime: *datetime
  will_paginate: *will_paginate
  activerecord:
    <<: *activerecord
    errors:
      models:
        user: *devise_errors
  app:
    routes: *routes
    categories: *categories
    messages: *messages

と言う所で、上記例のようにYAMLファイルをリファクタリングして行く方法を説明します。

YAMLのアンカーとエイリアスを理解する

まず最初にYAMLのアンカーとエイリアスを理解する必要があります。それとスペシャルキーを使ったマージの仕様を理解します。

アンカーの利用

YAMLでアンカーってあまり聞かないですよね。

以下例の&dateとあるのがアンカーです。エイリアス(*)を使ってアンカー以下全てを参照できるようになります。

date: &date # アンカー
  abbr_day_names:
  - 
  - 
  - 
  - 
  - 
  - 
  - 
my_date: *date # エイリアス。my_date.abbr_day_namesと利用できる。

マージの利用

YAMLのマージもあまり聞かないですよね。<<を使って現在の階層に他要素を組み込めます。

例えば以下yamlファイルをrubyのオブジェクトに変換してみます。

変換前のyamlファイル
a: &a
 aa: aa
b:
 <<: *a
 bb: bb
変換後のrubyオブジェクト
{
  "a" => {
    "aa" => "aa"
  },
  "b" => {
    "aa" => "aa",
    "bb" => "bb"
  }
}

"b"エントリーに"a"エントリーの内容がマージされているのが分かりますね。

リファクタリングする

さあアンカーとエイリアスとマップのマージ。この3つが理解できれば問題なくYAMLファイルのリファクタリングを進められますね。

先頭にアンカーを記述して、末尾でエイリアスを使って参照する仕組みにします。長くなるので部分抜粋+中間を略しています。

ja.yml
#
# https://github.com/svenfuchs/rails-i18n/blob/master/rails/locale/ja.yml
#
date: &date
  abbr_day_names:
  - 
  - 
  - 
  ...略...

datetime: &datetime
  distance_in_words:
    about_x_hours:
      one: 約1時間
      other: 約%{count}時間
    about_x_months:
      one: 約1ヶ月
      other: 約%{count}ヶ月
    ...略...
#
# https://github.com/kano4/troch/blob/master/config/locales/devise.ja.yml
#
devise: &devise
  confirmations:
    confirmed: 'アカウントを登録しました。'
    send_instructions: 'アカウントの有効化について数分以内にメールでご連絡します。'
    send_paranoid_instructions: "あなたのメールアドレスが登録済みの場合、本人確認用のメールが数分以内に送信されます。"
    ...略...

devise_errors: &devise_errors 
  attributes:
    email:
      blank: "入力必須項目です。"
      invalid: "無効なメールアドレスです。"
      taken: "このメールアドレスは既に登録されています。"
      ...略...
#
# My application models.
#
activerecord: &activerecord
  models:
    site: サイト
    user: ユーザー
  attributes:
    site:
      id: サイトID
      name: サイト名
      ...略...

ja:
  date: *date
  datetime: *datetime
  devise: *devise
  activerecord:
    <<: *activerecord
    errors:
      models:
        user: *devise_errors

リファクタリングのポイントとしては以下2点です。

  1. dateやdatetimeやdevise等が混ざらないように第一階層にアンカーとしてそれをエイリアスで参照する。
  2. 複数エントリーを組み合わせるactiverecord.errors.modelsのような箇所はマージを使う。

ここまでスッキリしていればYAMLファイルのメンテナンスが苦になりませんね!

さいごに

StackOverFlowとか見てみても、これといったシンプルな解決方法がなかったのでQiitaにまとめました。

もし重複行を教えてくれるYAMLエディターがあれば(探してもありませんでしたが)リファクタリングをする必要も無さそうです。

質問などあればコメント欄またはTwitter宛にお願いします。

リファレンス情報

41
32
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
41
32