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のオブジェクトに変換してみます。
a: &a
aa: aa
b:
<<: *a
bb: bb
{
"a" => {
"aa" => "aa"
},
"b" => {
"aa" => "aa",
"bb" => "bb"
}
}
"b"エントリーに"a"エントリーの内容がマージされているのが分かりますね。
リファクタリングする
さあアンカーとエイリアスとマップのマージ。この3つが理解できれば問題なくYAMLファイルのリファクタリングを進められますね。
先頭にアンカーを記述して、末尾でエイリアスを使って参照する仕組みにします。長くなるので部分抜粋+中間を略しています。
#
# 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点です。
- dateやdatetimeやdevise等が混ざらないように第一階層にアンカーとしてそれをエイリアスで参照する。
- 複数エントリーを組み合わせるactiverecord.errors.modelsのような箇所はマージを使う。
ここまでスッキリしていればYAMLファイルのメンテナンスが苦になりませんね!
さいごに
StackOverFlowとか見てみても、これといったシンプルな解決方法がなかったのでQiitaにまとめました。
もし重複行を教えてくれるYAMLエディターがあれば(探してもありませんでしたが)リファクタリングをする必要も無さそうです。
質問などあればコメント欄またはTwitter宛にお願いします。
リファレンス情報
- YAMLをRubyへ変換する時に困らなくなる記事
- http://qiita.com/tkosuga@github/items/8ed6e45788648f5a089d
- Yaml Cookbook (For Ruby)
- http://yaml.org/YAML_for_ruby.html