0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

第32章|今さら学ぶ「国際化(i18n)」

0
Last updated at Posted at 2026-03-04

第32章|今さら学ぶ「国際化(i18n)」

📚 シリーズ目次はこちら → 「今さら学ぶ」シリーズ — はじめに
🗺️ KnowledgeNoteの設計を確認 → 設計マップ

この章でわかること

  • i18nとは — アプリに「翻訳辞書」を持たせる仕組み
  • なぜ日本語専用アプリでもi18nを使うのか
  • ロケールファイルの管理 — 日本語・英語の辞書を分けて管理
  • 翻訳キーの設計 — 辞書の引き方にルールを決める
  • モデルのバリデーションメッセージを日本語化する
  • 日時フォーマットのローカライズ

🏠 たとえ話で掴む「i18n」

i18n(internationalizationの略。iとnの間の18文字を省略した略称) は、アプリに 翻訳辞書 を持たせる仕組みです。

旅行ガイドブックを想像してください。「こんにちは」を英語で言いたいとき、和英辞書を引けば「Hello」と出てきます。i18nも同じで、アプリのコードに直接「こんにちは」と書く代わりに、 辞書キー で引くようにします。

# ❌ コードに直接日本語を書く
flash[:notice] = "記事を投稿しました"

# ✅ 辞書キーで引く
flash[:notice] = t("articles.create.success")
# → 日本語辞書なら「記事を投稿しました」
# → 英語辞書なら「Article has been posted」

辞書を切り替えるだけで、コードを変えずに多言語対応できます。


i18nとは何か — 技術的な定義

Railsの i18n(Internationalization) は、アプリケーションのテキストをコードから分離し、外部のロケールファイル(YAML)で管理する仕組みです。Rails標準で組み込まれており、追加gemなしで使えます。

なぜi18nが必要なのか

「多言語対応しないから関係ない」と思われがちですが、日本語専用のアプリでもi18nが必要になる場面があります。

1. バリデーションエラーメッセージの日本語化

Railsのバリデーションエラーは、デフォルトでは英語で表示されます。

# デフォルト(英語)
Name can't be blank
Email address has already been taken

# i18nで日本語化した場合
ユーザー名を入力してください
メールアドレスはすでに使用されています

ユーザーに見えるエラーメッセージが英語のままでは、日本語のアプリとして不自然です。バリデーションの仕組みについては(→ 第12章で詳しく扱います)。

2. モデル名・属性名の統一管理

フォームのラベル、エラーメッセージ、管理画面での表記を一箇所で管理できます。属性名を変更したいとき、ロケールファイルの1行を変えるだけで全画面に反映されます。

3. 日時フォーマットの統一

2025-02-15 10:30:00 を 2025年2月15日 10:30 のように表示するフォーマットも、ロケールファイルで一元管理できます。

i18nの仕組み

i18nは次の3つの要素で構成されています。

要素 役割 たとえ
ロケールファイル 翻訳データを保存するYAMLファイル 辞書そのもの
t() メソッド キーを指定して翻訳を取得する 辞書を引く動作
I18n.locale どの言語の辞書を使うかの設定 「今は和英辞書を使う」という切り替え
# ロケール設定 → t() で辞書を引く → 対応する翻訳が返る
I18n.locale = :ja
t("articles.create.success")  # => "記事を投稿しました"

I18n.locale = :en
t("articles.create.success")  # => "Article has been posted"

📖 ロケールファイル — 辞書を作る

日本語ロケールファイル

# config/locales/ja.yml
ja:
  activerecord:
    models:
      user: ユーザー
      article: 記事
      comment: コメント
    attributes:
      user:
        name: ユーザー名
        email_address: メールアドレス
        password: パスワード
        password_confirmation: パスワード(確認)
      article:
        title: タイトル
        body: 本文
        status: ステータス
      comment:
        body: コメント本文
    errors:
      messages:
        blank: を入力してください
        too_long: は%{count}文字以内で入力してください
        too_short: は%{count}文字以上で入力してください
        taken: はすでに使用されています
        invalid: は不正な値です

  articles:
    index:
      title: 記事一覧
    create:
      success: 記事を投稿しました
      failure: 記事の投稿に失敗しました
    update:
      success: 記事を更新しました
    destroy:
      success: 記事を削除しました

  layouts:
    header:
      home: ホーム
      articles: 記事一覧
      users: ユーザー
      login: ログイン
      logout: ログアウト
      signup: 新規登録

英語ロケールファイル

# config/locales/en.yml
en:
  activerecord:
    models:
      user: User
      article: Article
      comment: Comment
    attributes:
      user:
        name: Username
        email_address: Email address
        password: Password
        password_confirmation: Password confirmation
      article:
        title: Title
        body: Body
        status: Status
      comment:
        body: Comment body

  articles:
    index:
      title: Articles
    create:
      success: Article has been posted
      failure: Failed to post article
    update:
      success: Article has been updated
    destroy:
      success: Article has been deleted

  layouts:
    header:
      home: Home
      articles: Articles
      users: Users
      login: Log in
      logout: Log out
      signup: Sign up

デフォルトロケールの設定

# config/application.rb
config.i18n.default_locale = :ja
# → デフォルトの言語を日本語に
config.i18n.available_locales = [:ja, :en]
# → 利用可能な言語を日本語と英語に制限
config.i18n.fallbacks = true
# → 翻訳が見つからないとき、デフォルトロケールにフォールバック

rails-i18n gem — 日本語のデフォルト翻訳

Railsが内部で使うメッセージ(曜日名、月名、バリデーションのデフォルトメッセージ等)は、自分で全て書く必要はありません。rails-i18n gemが各言語のデフォルト翻訳を提供しています。

# Gemfile
gem "rails-i18n", "~> 8.0"
# → 日本語の曜日名(日曜日〜土曜日)、月名、エラーメッセージの
#   デフォルト翻訳がまとめて入る
$ bundle install

このgemを入れると、date.day_names や errors.messages.blank といった基本的な翻訳が自動で日本語になります。アプリ固有の翻訳(モデル名、フラッシュメッセージ等)だけ自分で書けば済みます。


🔑 翻訳キーの設計ルール

ビューでの使い方

<%# t("キー") で翻訳を呼び出す %>
<h1><%= t("articles.index.title") %></h1>
<%# → 「記事一覧」(日本語)or 「Articles」(英語) %>

<%# 省略記法(Lazy Lookup)— ビューのパスから自動でキーを推定 %>
<%# app/views/articles/index.html.erb 内で %>
<h1><%= t(".title") %></h1>
<%# → articles.index.title として解釈される %>

省略記法( Lazy Lookup)は便利ですが、どの翻訳キーが使われているかがコードから読み取りにくくなる面もあります。チームで方針を決めておくのが無難です。

コントローラでの使い方

# app/controllers/articles_controller.rb
def create
  @article = current_user.articles.build(article_params)
  if @article.save
    redirect_to @article, notice: t("articles.create.success")
  else
    flash.now[:alert] = t("articles.create.failure")
    render :new, status: :unprocessable_entity
  end
end

モデル名・属性名の日本語化

# ロケールファイルの activerecord.models / .attributes を設定すると…
Article.model_name.human                  # => "記事"
Article.human_attribute_name(:title)      # => "タイトル"

# バリデーションエラーメッセージが自動で日本語になる
# "Title can't be blank" → "タイトルを入力してください"

# form_with のラベルも自動で日本語になる
# <%= f.label :title %>  → <label>タイトル</label>

翻訳が見つからなかったとき

存在しないキーを指定すると、画面に translation missing: ja.some.key と赤文字で表示されます。

<%= t("articles.nonexistent_key") %>
<%# → "translation missing: ja.articles.nonexistent_key" %>

開発中にこの表示を見かけたら、ロケールファイルにキーの追加が必要です。default オプションでフォールバック値を指定することもできます。

t("articles.nonexistent_key", default: "記事")
# → キーが見つからなければ "記事" を返す

📅 日時フォーマットのローカライズ

# config/locales/ja.yml
ja:
  time:
    formats:
      default: "%Y年%m月%d日 %H:%M"
      short: "%m/%d %H:%M"
      long: "%Y年%m月%d日(%A) %H:%M"
  date:
    formats:
      default: "%Y年%m月%d日"
<%= l(@article.created_at) %>
<%# → "2025年02月15日 10:30" %>

<%= l(@article.created_at, format: :short) %>
<%# → "02/15 10:30" %>

<%= l(@article.created_at, format: :long) %>
<%# → "2025年02月15日(土曜日) 10:30" %>
<%# ※ 曜日名は rails-i18n gem で日本語が提供される %>

l( localize の略)メソッドで、日時をロケールに応じたフォーマットで表示します。t が翻訳テキスト用、l が日時・日付用です。


🌐 URLでロケールを切り替える

多言語対応する場合は、URLにロケールを含めてどの言語で表示するかを指定する方法が一般的です。

# config/routes.rb
scope "(:locale)", locale: /ja|en/ do
  resources :articles
end
# → /ja/articles(日本語)
# → /en/articles(英語)
# → /articles(デフォルト = 日本語)
# app/controllers/application_controller.rb
around_action :switch_locale

private

def switch_locale(&action)
  locale = params[:locale] || I18n.default_locale
  I18n.with_locale(locale, &action)
end

# URLヘルパーにlocaleパラメータを自動で含める
def default_url_options
  { locale: I18n.locale == I18n.default_locale ? nil : I18n.locale }
  # → デフォルトロケール(日本語)のときはlocaleパラメータを省略
  # → /articles(日本語), /en/articles(英語)
end

I18n.with_locale はブロック内だけロケールを変更するメソッドです。リクエスト処理が終わると元に戻るため、他のリクエストに影響を与えません。


🛠️ KnowledgeNoteでの具体例

enum の翻訳

# config/locales/ja.yml
ja:
  enums:
    article:
      status:
        draft: 下書き
        published: 公開中
        archived: アーカイブ
<%# app/views/articles/show.html.erb %>
<h1><%= @article.title %></h1>
<p>
  by <%= @article.user.name %> ·
  <%= l(@article.created_at, format: :short) %>
</p>

<% if @article.published? %>
  <span class="bg-green-100 text-green-800 px-2 py-1 rounded">
    <%= t("enums.article.status.published") %>
  </span>
<% end %>

ロケールファイルの分割管理

ファイルが大きくなったら、ディレクトリで分割できます。Railsは config/locales/ 以下のYAMLファイルを自動で読み込みます。

config/locales/
├── ja.yml              # 共通翻訳(レイアウト等)
├── en.yml
├── models/
│   ├── ja.yml          # ActiveRecordのモデル名・属性名
│   └── en.yml
└── views/
    ├── articles/
    │   ├── ja.yml      # 記事関連の翻訳
    │   └── en.yml
    └── users/
        ├── ja.yml
        └── en.yml
# config/application.rb
# サブディレクトリのYAMLも自動読み込みする設定
config.i18n.load_path += Dir[Rails.root.join("config", "locales", "**", "*.yml")]

💼 面接で聞かれたら?

Q:Railsのi18nについて説明してください。

「i18nはRails標準の国際化機能で、アプリの表示テキストをロケールファイル(YAML)で管理します。コードに直接テキストを書く代わりに t("キー") で辞書を引くことで、ロケールを切り替えるだけで多言語対応できます。日本語専用のアプリでも、バリデーションエラーメッセージの日本語化やモデル属性名の一元管理にi18nを使います。」

深掘りされたら:

  • 「日本語専用でもi18nを使う理由は?」→ Railsのバリデーションエラーはデフォルトで英語。activerecord.attributes でモデル属性名を定義すると、エラーメッセージやフォームラベルが自動で日本語になる。表記の一元管理にもなる。
  • 「t と l の違いは?」→ t(translate)はテキストの翻訳に使い、l(localize)は日時のフォーマットに使う。l(@article.created_at) で「2025年02月15日 10:30」のようにロケールに応じた表示になる。
  • 「翻訳が見つからないときはどうなる?」→ translation missing: ja.xxx.yyy という文字列が表示される。config.i18n.fallbacks = true を設定すると、見つからない場合にデフォルトロケールの翻訳にフォールバックする。

🔗 もっと深く知りたい人へ(1次情報リンク)


まとめ

  • ✅ i18nは「翻訳辞書」。コードにテキストを直接書かず、t("キー") で辞書を引く仕組み
  • ✅ 日本語専用アプリでも、バリデーションエラーの日本語化・属性名の一元管理にi18nを使う
  • ✅ ロケールファイル(YAML)で日本語・英語等の辞書を分けて管理する
  • ✅ rails-i18n gemを入れると、曜日名やデフォルトエラーメッセージの日本語翻訳がまとめて入る
  • ✅ l() メソッドで日時をロケールに応じたフォーマットで表示する
  • ✅ URLにロケールを含める方式で、言語の切り替えに対応できる

📚 シリーズ目次:「今さら学ぶ」シリーズ — はじめに

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?