もふもふ技術部

IT技術系mofmofメディア

【Rails I18n】URLで言語切り替えする

アクセスしたURLによってlocaleを切り替える機能を意外と実装したことがなかったので、今回は3つの方法でlocaleを切り替えてみたいと思います。

事前準備

複数の言語を使用できるように設定する

config/application.rb に以下の設定を追加します。

config.i18n.available_locales = %i(ja en)
config.i18n.enforce_available_locales = true
config.i18n.default_locale = :ja
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s]
localeファイルを設置する

config/locales/ja.ymlconfig/locales/en.yml など必要なファイルを設置します。

URLのパスで言語を判断する場合

www.hohoge.com/ja/docs や、www.hohoge.com/en/docs のようにURLのパスで判断する場合の実装方法です。
www.hohoge.com/docs のように言語が指定されていない場合はデフォルトの言語を使用します。

1. ルーティングを設定する

config/routes.rb

Rails.application.routes.draw do
  scope '(:locale)', locale: /#{I18n.available_locales.map(&:to_s).join('|')}/ do
    ## 省略
  end
end

全てのルーティングを scope '(:locale)', locale: /#{I18n.available_locales.map(&:to_s).join('|')}/ do ブロックで囲むようにしましょう!

2. コントローラーに設定を追加する

app/controllers/application_controller.rb

class ApplicationController < ActionController::Base
  around_action :switch_locale

  private
  
  def switch_locale(&action)
    I18n.with_locale(locale, &action)
  end

  def locale
    @locale ||= params[:locale] || I18n.default_locale
  end
end

トップレベルドメインで言語を判断する場合

hogehoge.comhogehoge.es など、トップレベルドメインで判断する場合の実装方法です。
.com はデフォルトの言語を使うようにします。

1. ルーティングの設定

特に必要ありません。

2. コントローラーに設定を追加する

app/controllers/application_controller.rb

class ApplicationController < ActionController::Base
  around_action :switch_locale

  private
  
  def switch_locale(&action)
    I18n.with_locale(locale, &action)
  end

  def locale
    parsed_locale = request.host.split('.').last
    @locale ||= if I18n.available_locales.map(&:to_s).include?(parsed_locale)
      parsed_locale
    else
      I18n.default_locale
    end
  end
end

サブドメインで言語を判断する場合

ja.hogehoge.comen.hogehoge.com など、サブドメインで判断する場合の実装方法です。
サブドメインがない場合はデフォルトの言語を使うようにします。

1. ルーティングの設定

特に必要ありません。

2. コントローラーに設定を追加する

app/controllers/application_controller.rb

class ApplicationController < ActionController::Base
  around_action :switch_locale

  private
  
  def switch_locale(&action)
    I18n.with_locale(locale, &action)
  end

  def locale
    parsed_locale = request.subdomain
    @locale ||= if I18n.available_locales.map(&:to_s).include?(parsed_locale)
      parsed_locale
    else
      I18n.default_locale
    end
  end
end

終わり

普段の開発ではほとんど使わない設定やメソッドが多かったですが、出来上がった実装を見てみると意外と少ない記述で済んでビックリしました!