更新日:
【Rails】 I18n入門書~日本語化対応の手順と応用的な使い方
I18nとは、ある言語の文言を別の言語の文言に翻訳してくれる機能のことです。
以下のようにデフォルトで使用する言語を設定し、config/locales/
以下に翻訳ファイルを配置することで、現在の言語に対応する翻訳文を取得して表示します。
1
2
3
4
5
module I18nApp
class Application < Rails::Application
config.i18n.default_locale = :ja # 追加
end
end
1
2
3
4
5
6
7
8
9
10
11
ja:
activerecord:
errors:
models:
user:
attributes:
name:
blank: "空になっています。入力してください。"
age:
blank: "空になっています。入力してください。"
# 省略
I18nを使うと、以下の画像のようなvalidationのエラー表示も日本語に翻訳することが出来ます。
また、翻訳だけではなく、現地の日付のフォーマットに変換することもできます。
基本的な使い方
この章では、I18nの設定方法や基本的な使い方について解説します。
アプリケーションを日本語化対応する手順
i18n_app
アプリケーションを日本語化する手順を解説します。
以下は作成するアプリケーションの完成図です。
以下の手順で作成していきます。
- デフォルト言語の設定
- 翻訳ファイルの作成
- 翻訳ファイルの設定
- エラーメッセージの確認
I18nを使ったことがない方は、一緒にアプリケーションを作成して理解を深めていきましょう。
前準備:サンプルアプリケーション用意
まずは、rails newでi18n_app
アプリケーションを作成します。
1
rails _5.2.1_ new i18n_app -d mysql
以下のように作成したi18n_app
のディレクトリに移動して、簡易的なユーザー登録や一覧機能を一気に作成してくれるscaffold
を実行します。
1
2
3
cd i18n_app # ディレクトリを移動
rails g scaffold User name:string age:integer
# rails g scaffold モデル名 カラム名:型 カラム名:型
このコマンドでnameカラム、ageカラムを含めたusersテーブルが作成されて、ユーザーを作成するフォームも自動で作成されています。今回はこのフォームを使って解説します。
そして、以下のコマンドを実行してデータベースの作成を行います。
1
2
bundle exec rails db:create && rails db:migrate
# scaffoldの内容を元にして作成されたマイグレーションファイルを実行してデータベースを作成
次に、Userモデルに以下のvalidationを追加します。validationに引っかかった際は、エラーメッセージが表示されます。
1
2
3
class User < ApplicationRecord
validates :name, :age, presence: true
end
このvalidationを追加することによって、フォームからユーザーを作成するときにnameとageの項目が空であればエラーが出ます。
また、以下のコードの<h1>New User</h1>
は、scaffold
で自動で作成された部分なので日本語に変更します。
1
2
3
4
5
6
7
<h1>New User</h1> <!--変更前-->
<h1>新規登録</h1> <!--変更後-->
<%= render 'form', user: @user %>
<%= link_to 'Back', users_path %> <!--変更前-->
<%= link_to '戻る', users_path %> <!--変更後-->
サーバーを起動させて「localhost:3000/users/new」にアクセスし、以下の画像のようにフォームに何も入力しないでユーザーを作成すると、エラーメッセージが表示されます。
英語のエラーメッセージが表示されていれば、アプリケーションの雛形は完成です。
h1のNew User
を手動で新規登録
に変更した箇所とは違い、このエラーメッセージは、Railsアプリケーションによって自動で付与されます。デフォルトでは英語になってしまうので、デフォルト言語を日本語に変更して、英語のエラーメッセージを日本語に翻訳する翻訳ファイルを作成します。
1. デフォルト言語の設定
デフォルト言語を英語から日本語に設定するには、以下のコードをconfig/application.rb
に追加します。
1
2
3
4
5
module I18nApp
class Application < Rails::Application
config.i18n.default_locale = :ja # 追加
end
end
2. 翻訳ファイルの作成
日本語の翻訳を設定するファイルを作成する為に、config/locales
以下にデフォルト言語で設定した名前のyamlファイル(ja.yml
)を作成します。
config/locales
以下に翻訳する言語の設定ファイルを配置すると、自動で読み込まれます。
i18n_app
ディレクトで以下のコマンドを実行して、ファイルを作成します。
1
touch config/locales/ja.yml
ja.yml
ファイルには、以下のコードを記述します。
1
2
ja:
activerecord:
次の章で、ja.yml
ファイルにエラーメッセージを翻訳する詳しい設定方法について解説します。
3. 翻訳ファイルの設定
翻訳ファイルの設定の解説をする前に、ymlファイルの使い方について触れます。
ymlファイルの基本的な書き方は、以下のようにインデントを使うことで、データの階層構造を表現することが出来ます
1
2
3
4
ja:
word:
greeting:
hello: "こんにちは" # このデータが欲しい
階層構造になったデータにアクセスするには、以下のコードのように階層を.
で繋いだ文字列をtメソッド
に渡します。
tメソッド
については、後述します。
1
2
irb(main):001:0> I18n.t("word.greeting.hello")
=> "こんにちは"
そして、このja.yml
ファイルに翻訳を追加する際は、以下の点に気をつけてください。
それでは、i18n_app
アプリケーションの日本語化する手順について確認します。
ここまでの日本語翻訳の設定を反映させる為に、一度サーバーを再起動させて「localhost:3000/users/new」にアクセスし、フォームに何も入力しないで新規登録を行うと、以下のようにtranslation missing
のエラーが発生します。
通常、I18nは設定した言語に応じてconfig/locales/
以下から対応する翻訳ファイルを読み込んで、その言語に翻訳してくれますが、今回の場合は、以下の画像のように日本語に設定したのに、「エラーメッセージに対応する日本語の翻訳が見つからない」というエラーが発生しています。
現在、翻訳ファイルは以下のコードのように初期設定のみ記述しているので、日本語に翻訳する事が出来ません。
1
2
ja:
activerecord:
この翻訳ファイル(ja.yml
)に、エラーメッセージが対応する日本語訳を設定する事で、translation missing
を解決して日本語に表示することが出来ます。
翻訳ファイルに設定するName
とAge
のエラーメッセージのキーは、以下の画像の通りです。
冒頭でも少し触れましたが、上記のキーを繋げる.
は翻訳ファイルの階層を表しています。翻訳ファイルに、この階層通りにキーを配置して訳文を記述することで、エラーメッセージを正しく設定することが出来ます。
1
2
3
4
5
# Nameが空だった場合に、日本語に翻訳されるエラーメッセージのキー
ja.activerecord.errors.models.user.attributes.name.blank
# Ageが空だった場合に、日本語に翻訳されるエラーメッセージのキー
ja.activerecord.errors.models.user.attributes.age.blank
翻訳ファイルの階層は、インデントを使って記述します。Nameの値が空だった場合は、以下の画像のようにインデントでエラーメッセージの階層を表現します。
また、Name
とAge
のエラーメッセージのキーはattributes
まで階層が一緒なので、以下のように記述する事が出来ます。日本語で表示したい訳文をblank
の箇所に記述します。
1
2
3
4
5
6
7
8
9
10
ja:
activerecord:
errors:
models:
user:
attributes:
name:
blank: "Nameが空だった場合の日本語のエラーメッセージを入れる"
age:
blank: "Ageが空だった場合の日本語のエラーメッセージを入れる"
このように翻訳ファイルには、階層を表現するためにインデントを使ってキーを記述します。それでは、最後にblankを以下のように記述しましょう。
1
2
3
4
5
6
7
8
9
10
ja:
activerecord:
errors:
models:
user:
attributes:
name:
blank: "空になっています。入力してください。"
age:
blank: "空になっています。入力してください。"
4. エラーメッセージの確認
config/以下のファイルの内容を変更した場合は、変更を反映させる為にサーバーを再起動させる必要があるので、一度サーバーを再起動させてから「localhost:3000/users/new」にアクセスします。
フォームを空にしてユーザーを作成すると、以下の画像のようにエラーメッセージが日本語で表示されるようになりました。
ここまでが、I18nを使って日本語に翻訳する為の基本的な手順になります。
ちなみに以下のエラーメッセージの部分は、コードを変更するだけで日本語表記に出来ます。
1
2
3
4
5
<!-- 変更前 -->
<h2><%= pluralize(user.errors.count, "error") %> prohibited this user from being saved:</h2>
<!-- 変更後 -->
<h2><%= user.errors.count %> 件のエラーが発生しました</h2>
コードを上記に変更すると、以下のように日本語で表示出来ます。
英語で表示されてる他の箇所(Name, Age, submit)は、I18nを使って日本語へ翻訳する必要がありますが、この後のmodelやsubmitの日本語化の章で解説させて頂きます。
modelを日本語化対応する設定
modelやmodelの属性を日本語化するには、以下のキーを翻訳ファイルに設定します。
1
2
3
4
5
# モデル名
ja.activerecord.models.モデル名
# モデルの属性
activerecord.attributes.モデル名.属性
上記を翻訳ファイルに設定する事で、ユーザー登録の以下の部分を日本語へ翻訳することが出来ます。
この部分は、以下のようにform_withの第一引数に「Userモデルのインスタンス(model: user)の情報」をFormBuilderオブジェクト(form
)に渡しているので、<%= form.label :name %>
でUserモデルのname属性をラベル名として表示する事ができます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<%# model: userには、部分テンプレートで@user = User.newが渡される %>
<%= form_with(model: user, local: true) do |form| %>
<%# 省略 %>
<div class="field">
<%= form.label :name %>
<%= form.text_field :name %>
</div>
<div class="field">
<%= form.label :age %>
<%= form.number_field :age %>
</div>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
上記では、Userモデルのname,age属性を使っているので、Userモデルのname,age属性を取得するymlファイルのキーは以下になります。
1
2
3
4
5
6
7
8
# Userモデル名の設定
ja.activerecord.models.user
# Userモデルのnameの設定
ja.activerecord.attributes.user.name
# Userモデルのageの設定
ja.activerecord.attributes.user.age
以下のように、models
から下のコードをja.yml
ファイルに追加します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
ja:
activerecord:
errors:
models:
user:
attributes:
name:
blank: "空になっています。入力してください。"
age:
blank: "空になっています。入力してください。"
models: #ここから下のコードを追加
user: "ユーザー"
attributes:
user:
name: "名前"
age: "年齢"
上記を確認すると、attributes
の下の階層にname
やage
の属性名ではなくuser
が入っています。
これは、以下の画像のようにラベルを作成する際に、Userモデルの情報を持つformの中のname
やage
の属性を使っているので、翻訳ファイルにも属性名の前にuser
を入れる必要があるからです。
formオブジェクトにはユーザーモデルの情報が入っているので、attributes、モデル名(今回の場合はuser)以下のカラム名を見に行くように設定されます。
ja.yml
にmodelの日本語を追加したら、サーバーを再起動させて「localhost:3000/users/new」にアクセスすると、以下の画像のようにラベルを日本語に翻訳する事が出来ました。
また、エラーメッセージも日本語に翻訳されている事が確認できます。
フォームオブジェクトについては、こちらの書籍で詳しく解説されています。体系的に学びたい方はおすすめの良書です。
submitを日本語化対応する設定
ja.helpers.submit
以下に設定する事で、デフォルトのsubmitも日本語に翻訳する事が出来ます。
先ほどのユーザー登録のsubmitは、以下の画像のようにモデル名だけ翻訳され中途半端なボタンになっています。
以下のように、helpers
から下のコードをja.yml
ファイルに追加します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
ja:
activerecord:
errors:
models:
user:
attributes:
name:
blank: "空になっています。入力してください。"
age:
blank: "空になっています。入力してください。"
models:
user: "ユーザー"
attributes:
user:
name: "名前"
age: "年齢"
helpers: # ここから下を追加する
submit:
create: 登録する
update: 更新する
submit: 保存する
サーバーを再起動させて「localhost:3000/users/new」にアクセスします。
上記の画像のように、submitを「登録する」という日本語に翻訳する事が出来ました。
このsubmitの表示は、form_withに渡されるUserモデルの状態に応じて変更されます。例えば、すでにUserモデルの情報が存在する場合は、updateの翻訳を見に行き「更新する」と表示されます。
I18nの主要なメソッド
I18nには、以下の主要なメソッドがあります。
- translateメソッド -
config/locales
以下の翻訳ファイルの参照 - localizeメソッド - 日付や時刻を設定した言語のフォーマットに変換する
以下のように翻訳ファイルの訳文を参照したり、日付をフォーマットに変換することが出来ます。
1
2
3
4
5
[1] pry(main)> I18n.translate("word.greeting.hello")
=> "こんにちは"
[2] pry(main)> I18n.localize(Date.today)
=> "2020/04/15"
また、上記のtranslate
メソッドとlocalize
メソッドは、以下のようにt
メソッドとl
メソッドを使ってシンプルに記述することが出来ます。(こちらのメソッドで解説していきます。)
1
2
3
4
5
[1] pry(main)> I18n.t("word.greeting.hello")
=> "こんにちは"
[2] pry(main)> I18n.l(Date.today)
=> "2020/04/15"
それでは、各メソッドについて解説していきます。
translateメソッド
translateメソッドは、config/locales/
以下の翻訳ファイルを参照することが出来ます。
例えば、翻訳ファイルに以下のような階層で日本語翻訳が設定してある場合は、I18n.t
メソッドにja:
以下の階層の文字列を渡す事で参照することが出来ます。
1
2
3
4
ja:
word:
greeting:
hello: "こんにちは" # このデータが欲しい
1
2
[1] pry(main)> I18n.t("word.greeting.hello")
=> "こんにちは"
また、scope
オプションを使って以下のようにシンボルで記述することも出来ます。
1
2
[1] pry(main)> I18n.t(:hello, scope: [:word, :greeting])
=> "こんにちは"
I18n.tを省略する
Controllerやviewファイルでは、以下のようにI18n.t()
をt()
に省略して記述することが出来ます。
1
2
<h1>新規登録</h1>
<%= t("word.greeting.hello") %> <%# 追加するコード %>
コンソールでは、省略することが出来ないので注意してください。
上記のようにt("word.greeting.hello")
を実行した場合は、NomethodError
のエラーが発生してます。
localizeメソッド
localize
メソッドは、DateオブジェクトやTimeオブジェクトをconfig/locales/
以下の翻訳ファイルに設定した日付や時刻のフォーマットに変換することが出来ます。
例えば、デフォルトでは以下のコードのような形式で返ります。
1
2
3
4
5
[1] pry(main)> Date.today
=> Wed, 15 Apr 2020
[2] pry(main)> Time.now
=> 2020-04-15 22:48:50 +0900
変換するフォーマットを設定するために、翻訳ファイルに以下のように記述します。
1
2
3
4
5
6
7
ja:
date:
formats:
default: "%Y/%m/%d"
time:
formats:
default: "%y/%m/%d %H:%M"
そして、以下のようにI18n.l()
にDate.today
とTime.now
を渡す事で、それぞれ翻訳ファイルに設定したフォーマットに変換されます。
1
2
3
4
5
[1] pry(main)>I18n.l(Date.today)
=> "2020/04/15"
[2] pry(main)> I18n.l(Time.now)
=> "20/04/15 22:35"
default以外のフォーマットを追加する
以下のlong
とshort
のように、default
以外にもフォーマットを自由に追加することが出来ます。
1
2
3
4
5
6
ja:
date:
formats:
default: "%Y/%m/%d"
long: "%Y年%m月%d日" # 追加
short: "%m/%d" # 追加
default以外のフォーマットに変換したい場合は、I18n.l()
の第二引数に以下のように指定します。
1
2
3
4
5
[1] pry(main)> I18n.l(Date.today, format: :long)
=> "2020年04月15日"
[2] pry(main)> I18n.l(Date.today, format: :short)
=> "04/15"
第二引数の指定がない場合は、以下のようにdefault
のフォーマットに変換されます。
1
2
[1] pry(main)> I18n.l(Date.today)
=> "2020/04/15"
localizeメソッドは、翻訳ファイルのフォーマットに変換してくれますが、アプリケーションで使用する言語が1つに決まっている場合は、time_formats.rbで日付のフォーマットを指定するのも良いでしょう。
その他の翻訳ファイルの設定
翻訳ファイルを設定する際に、そのほかの便利な設定方法を解説します。
式展開
翻訳ファイルは、以下のように式展開を使うことで変数を渡すことが出来ます。
1
2
3
4
ja:
word:
greeting:
hello: "こんにちは、%{name}さん" # 式展開を使う
I18n.t()
の第二引数以降に変数名: "値"
を渡すと、以下のように変数の値を展開して汎用性のある文言にすることが出来ます。
1
2
3
4
5
6
[1] pry(main)> I18n.t("word.greeting.hello", name: "ぴっか")
=> "こんにちは、ぴっかさん"
# 以下でもok
[2] pry(main)> I18n.t(:hello, scope: [:word, :greeting], name: "ぴっか")
=> "こんにちは、ぴっかさん"
この変数に渡す値には、以下のようにモデルのインスタンスを使うことも出来ます。
1
2
3
4
5
6
7
8
9
10
[1] pry(main)> user = User.first
=> #<User:0x00007f80565a1fd0
id: 1,
name: "田中",
age: 18,
created_at: Thu, 16 Apr 2020 01:12:24 JST +09:00,
updated_at: Thu, 16 Apr 2020 01:12:24 JST +09:00>
[2] pry(main)> I18n.t("word.greeting.hello", name: user.name)
=> "こんにちは、田中さん"
lazy lookup
「lazy lookup」とは、「Controllerやviewファイルのディレクトリの階層」を翻訳ファイルに設定する事で、Controllerやviewファイルの内部で参照するキーを短縮してアクセスする事が出来る仕組みのことです。
例えば、翻訳ファイルを以下のようにapp/views/users/new.html.erb
の階層を設定します。
1
2
3
4
ja:
users: # app/views/users/を表す
new: # app/views/users/new.html.erbを表す
title: "ユーザー登録"
この設定をすると、以下のようにapp/views/users/new.html.erb
の内部からt .title
の記述だけで、users.new.title
を参照する事が出来ます。
1
2
<h1><%= t '.title' %></h1> <!-- 本来は t 'users.new.title' -->
<%= render 'form', user: @user %>
このようにControllerやviewファイルで翻訳ファイルを参照する際は、「lazy lookup」を使う事でキーを短縮して参照する事が出来ます。
応用的な使い方
この章では、I18nについて応用的な使い方を解説します。
「基本的な使い方」で作成したi18n_app
アプリケーションを使って解説するので、初期設定等を行なってない場合はアプリケーションを日本語化対応する手順を参照してください。
翻訳ファイルのテンプレートを使用する
基本的な使い方では、I18nの仕組みを理解するために1つ1つ手動で設定して解説しましたが、実際のアプリケーションでは、ja.activerecord.errors.models.user.attributes.name.blank
のキーに対して「空になっています。入力してください。」の様な翻訳ファイルの設定は行いません。
なぜなら、よく利用される英語から日本語に翻訳するパターンの内容(例: blank等)は、I18nテンプレートとしてGithubに公開されているからです。
このテンプレートファイルをダウンロードすると、翻訳ファイルの設定がかなり楽になるので、このテンプレートを利用します。また、管理しやすいようにviewやmodelで分ける手順も解説します。
1. テンプレートをダウンロードする
まずは、Githubから日本語のテンプレートをダウンロードするために、以下のコマンドをアプリケーションのディレクトリに移動して実行します。
1
2
cd i18n_app # ディレクトリを移動
curl -s https://raw.githubusercontent.com/svenfuchs/rails-i18n/master/rails/locale/ja.yml -o config/locales/ja.yml
上記を実行してconfig/locales/ja.yml
を確認すると、以下のようにテンプレートが反映されています。
サーバーを再起動させて「localhost:3000/users/new」にアクセスし、フォームに何も入力しないで新規登録を行うと、以下のようにテンプレートによって日本語に翻訳されたエラーメッセージが表示されます。
当然ですが、テンプレートはUserモデルの日本語化対応する設定を行なっていないので、ラベル部分は英語表記のままになります。
2. modelやviewにディレクトリを分ける
テンプレートを使用する際は、ja.yml
ファイルの記述量が多いので、管理しやすいようにmodelやviewの翻訳の設定を以下のように別のファイルに分ける事が出来ます。
1
2
3
4
5
6
7
config/locales
├── en.yml
├── ja.yml
├── models
│ └─ ja.yml
└── views
└─ ja.yml
Userモデルの設定を以下のように、config/locales/models/
以下の翻訳ファイルに記述します。
1
2
3
4
5
6
7
8
ja:
activerecord:
models:
user: "ユーザー"
attributes:
user:
name: "名前"
age: "年齢"
I18nは、現在のlocaleに対応する翻訳ファイル(ja.yml)は自動で読み込んでくれますが、上記のディレクトリ構成にしたmodelやviewの翻訳ファイルは自動で読み込まれません。
config/locales/以下に設定した翻訳ファイルが全て読み込まれるように、以下のコードを設定する必要があります。
1
2
3
4
5
6
7
8
9
module I18nApp
class Application < Rails::Application
config.load_defaults 5.2
config.i18n.default_locale = :ja
# 以下のコードを追加する
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s]
end
end
サーバーを再起動させて「localhost:3000/users/new」にアクセスして、以下のように確認するとUserモデルの翻訳が反映されてラベルを日本語に表示する事が出来ました。
今回解説したディレクトリ構成は、例として簡単な構成にしましたが、翻訳設定が多い場合はconfig/locales/models/
やconfig/locales/views/
以下にディレクトリを作成してmodelやviewごとに分けることもできます。
URLパラメーターでlocaleを設定
I18nでは、以下のようにURLクエリパラメータで使用したいlocaleを設定する事が出来ます。
1
2
http://localhost:3000/users/new?locale=en # 英語を使用する
http://localhost:3000/users/new?locale=ja # 日本語を使用する
上記は、ApplicationController
を以下のように記述する事でURLクエリパラメーターで送信されたlocaleに設定する事が出来ます。
1
2
3
4
5
6
7
8
class ApplicationController < ActionController::Base
around_action :switch_locale
def switch_locale(&action)
locale = params[:locale] || I18n.default_locale
I18n.with_locale(locale, &action)
end
end
参照:Railsガイド 2.2 リクエスト間でロケールを管理する
ちなみに、韓国語や中国語は、以下のように変更することが出来ます。
1
2
http://localhost:3000/users/new?locale=ko # 韓国語を使用する
http://localhost:3000/users/new?locale=zh-CN # 中国語を使用する
どちらもGithubにテンプレートが用意されているので、以下のようにconfig/locales/
以下に配置します。
ファイルには、翻訳したい文言を設定することで対応する言語に翻訳することが出来ます。
enum
enumとは、1つのカラムに指定した複数個の定数を保存できる仕組みですが、I18nを併用する事でこの定数名を設定したデフォルト言語に翻訳する事が出来ます。
それでは、i18n_app
アプリケーションにenumを追加して日本語化する手順を解説します。enumが分からない方は、enumチュートリアルを参考にしてください。
1.アプリケーションにenumを追加する
i18n_appアプリケーションにenumを追加するので、初期設定等を行なってない場合はアプリケーションを日本語化対応する手順を参照してください。
まずは、以下のコマンドを実行してusersテーブルにenum用のroleカラムを追加します。
1
rails g migration AddColumnToUser role:integer
作成されたマイグレーションファイルに、以下のようにnull: false
とdefault: 0(初期値には0)
を追加してマイグレーションを実行します。
1
2
3
4
5
class AddColumnToUser < ActiveRecord::Migration[5.2]
def change
add_column :users, :role, :integer, null: false, default: 0 # nullとdefaultを追加する
end
end
1
rails db:migrate
次に、モデルの定義を参考にして、以下のようにroleカラムの値(0,1,2)にそれぞれowner, member, guest
の定数を設定します。
1
2
3
class User < ApplicationRecord
enum role: { owner: 0, member: 1, guest: 2 }
end
ユーザーの登録フォームでrole(権限)
も登録出来るように、以下のコードを追加して権限のセレクトボックスを作成します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<%= form_with(model: user, local: true) do |form| %>
<%# name, ageのコードを省略 %>
<%# ここから下のコードを追加する %>
<div class="field">
<%= form.label :role %>
<%= form.select :role, User.roles.keys.map {|k| [k, k]}, {}, { class: 'form-control', style: 'margin-bottom: 15px;', data: {} } %>
</div>
<%# ここまで %>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
上記コードの詳しい解説は、「formにenumを追加する方法」を参考にしてください。
次に、roleのデータを登録できるようにするために、以下のようにUsersController
のストロングパラメーターにrole
を追加します。
1
2
3
4
5
class UsersController < ApplicationController
def user_params
params.require(:user).permit(:name, :age, :role) # roleを追加
end
end
そして、追加したUserモデルのrole名を「role」から「権限」に翻訳させるために、ja.yml
ファイルに以下を追加します。
1
2
3
4
5
6
7
8
9
ja:
activerecord:
models:
user: "ユーザー"
attributes:
user:
name: "名前"
age: "年齢"
role: "権限" # 追加する
サーバーを再起動させて「localhost:3000/users/new」にアクセスすると、以下のように権限のセレクトボックスが追加されています。
2. 権限の定数名を翻訳する
権限のセレクトボックスを追加することが出来ましたが、以下のように表示される定数名は英語表記のままです。この権限の定数名をI18nを使って日本語に翻訳します。
Userモデルに追加したenumの設定をもう一度確認しましょう。
1
2
3
class User < ApplicationRecord
enum role: { owner: 0, member: 1, guest: 2 }
end
上記を確認すると、roleの値はそれぞれowner, member, guest
が定数名として定義されているので以下のようにroles
以下に指定します。
1
2
3
4
5
6
7
8
9
10
11
12
13
ja:
activerecord:
models:
user: "ユーザー"
attributes:
user:
name: "名前"
age: "年齢"
role: "権限"
roles: # ここから下を追加
owner: "オーナー"
member: "メンバー"
guest: "ゲスト"
ja.yml
ファイルに設定した翻訳を表示できるように、日本語表示のselectboxを作成を参考にして、roleのセレクトボックスを以下のように変更します。
1
2
3
4
5
<%# 変更前 %>
<%= form.select :role, User.roles.keys.map {|k| [k, k]}, {}, { class: 'form-control', style: 'margin-bottom: 15px;', data: {} } %>
<%# 変更後 %>
<%= form.select :role, options_for_select(User.roles.map { |k, _v| [t("activerecord.attributes.user.roles.#{k}"), k] }), { class: 'form-control', style: 'margin-bottom: 15px;', data: {} } %>
サーバーを再起動させて再び「localhost:3000/users/new」にアクセスすると、以下のように権限のセレクトボックスを日本語に表示する事が出来ました。
注意点
enumにI18nを使い場合は、翻訳ファイルに設定するキー名に気をつけてください。
今回の権限の場合で考えると、以下のようにrole
配下の階層に定数名をそのまま定義する事が出来そうですが、これはenumの他の機能の仕様と重なってしまうため以下のようにエラーが発生します。
1
2
3
4
5
6
7
8
9
10
11
12
ja:
activerecord:
models:
user: "ユーザー"
attributes:
user:
name: "名前"
age: "年齢"
role: "権限" # role配下に定数名の翻訳を設定
owner: "オーナー"
member: "メンバー"
guest: "ゲスト"
そのため、以下のようにrole
と同じ階層にroles
を配置し、その中で定数名を定義する事で日本語の翻訳をする事が出来ます。
1
2
3
4
5
6
7
8
9
10
11
12
13
ja:
activerecord:
models:
user: "ユーザー"
attributes:
user:
name: "名前"
age: "年齢"
role: "権限"
roles: # roles以下に定数名の翻訳を設定
owner: "オーナー"
member: "メンバー"
guest: "ゲスト"
enumでI18nを使用する場合は、enumを使用するカラム名を複数形にして定数名を日本語へ翻訳するように気をつけてください。
この記事のまとめ
- I18nとは、ある言語の文言を別の言語の文言に翻訳してくれる機能のこと
- config/locales/以下に翻訳ファイルを配置することで、現在の言語に対応する翻訳文を取得して表示する
- エラーメッセージやアプリケーション内の文言をI18nに設定することで、国際化対応することが出来る