railsの個人開発でi18nで英語以外の言語も訳せてたらいいなと思っているあなたに

# 初めに
自身が作ったポートフォリオにて、実は英語などに翻訳させる機能を実装してます
自身が作った料理診断アプリは下記ですので、気になる人はご確認ください

https://qiita.com/jiantaiyiteng1/items/94f321646051001a72de

いざrailsで個人開発でできたアプリをリリースしても
```
日本人以外の人に触って多様な意見が欲しい
外国人にもわかりやすく使えたらいいよね
```
と上記のように英語以外の別言語で翻訳機能を実装してみたいと思う人も多いと思います
私は外国の知人に自身が作ったアプリを共有すると、「読めない」という意見があり、そのパブリックコメントをもとに追加実装しました
今回は英語以外の言語でもボタンを押すとその言語に変わるシステムを作成しようと思います

:::note warn
今回はコストを抑制した(お金をかけない)翻訳機能を実装します
Amazon Translate の自動翻訳機能を実装するなど、多言語機能の実装はいくつかありますが、
Amazon Translate はデータ超過すると課金されるのでご注意ください
詳しくはこちらをご参照ください

https://aws.amazon.com/jp/translate/pricing/

:::

# 1:gem 'rails-i18n'を導入する(まだi18nで日本語翻訳機能を実装していない場合)
公式記事をもとにgemfileにて、下記のようにrails-i18nを記述します
今回はgem 'rails-i18n', '~> 7.0.0'を使用します
https://rubygems.org/gems/rails-i18n?locale=ja

https://github.com/svenfuchs/rails-i18n
```ruby:gemfile
gem 'rails-i18n', '~> 7.0.0'
```
記述後bash環境の場合、下記のコマンドでインストールします
```bash
bundle install
```
docker環境の場合は、下記コマンドでインストールします
```bash
docker compose run web bundle install
```
なお、最初の日本語化対応が未対応の場合は、まず下記の記事をご確認ください

https://qiita.com/shimadama/items/7e5c3d75c9a9f51abdd5

https://qiita.com/taku-enginner/items/afec88307ca6c9476e21


# 2:app/controllers/application_controller.rbに翻訳させるためのアクションを作る
app/controllers/application_controller.rbに下記を記述します

```ruby:app/controllers/application_controller.rb
 before_action :require_login
 
  before_action :set_locale # 追加
# 省略  
```
### before_action
アクションが実行される前に指定されたメソッドを呼び出します
application_controller.rb に記述することで、ApplicationController クラスを継承しているすべてのコントローラでbefore_action が適用されます

### :set_locale
各リクエストの冒頭にロケールを設定して、リクエストが持続する間はすべての文字列が指定のロケールで翻訳されるようにします
ロケールはApplicationControllerのbefore_actionで設定できます

```ruby:app/controllers/application_controller.rb
# 省略(before_action :set_localeの下に記述)
def default_url_options
    { locale: I18n.locale }
end

private
# 省略
```
上のようにすることで、
url_forに依存するすべてのヘルパーメソッド (root_pathやroot_urlなどの名前付きメソッド,books_path,books_url等のリソースルーティングを持つヘルパー) では自動的にロケール情報がクエリ文字列に含みます
たとえば日本語の場合、下記の画面のように「http://localhost:3001/?locale=ja」
のような形式になります
[![Image from Gyazo](https://i.gyazo.com/3ea1b5ad248edceaa9f2ddb8f54002b4.png)](https://gyazo.com/3ea1b5ad248edceaa9f2ddb8f54002b4)

```ruby:app/controllers/application_controller.rb
# 省略(private指定の下部に記述してます)
  def set_locale
    I18n.locale = params[:locale] || I18n.default_locale
  end
# 省略  
```
### def set_locale ~ end
リクエスト間でロケールを管理します
I18n.localeを明示的に設定しない限り、すべての訳文でデフォルトのロケールが使われます
ローカライズされたアプリケーションは、将来複数ロケールのサポートが必要ですので、 これを行うためには、各リクエストの冒頭にロケールを設定して、リクエストが持続する間はすべての文字列が指定のロケールで翻訳されるようにしておきます

1の手順で翻訳させるための動きのベースは出来上がります

# 2:Railsのi18nのデフォルト設定を記述する
config/application.rbにおいて、下記のように「config.i18n.default_locale = :ja 」という記述がある場合、
```ruby:config/application.rb
    config.i18n.default_locale = :ja
```
「[]」を囲い「:ja」に「,:en」などと追加していきます
```ruby:config/application.rb
    config.i18n.available_locales = [:ja, :en]
```
上記の記載により、Railsアプリケーションのデフォルトの言語設定が日本語以外のほかの言語でも設定できます

また、i18nは嬉しいことに2025年2月現在733種類の言語要素を用意しています
下記の資料を参考にすると他の言語をRailsのi18nのデフォルト設定でどう記述するかが理解できます
国によっては、同じ言葉(英語、中国語など)でも歴史過程において、エリアによって字体の表現が異なるので、どのユーザーに提供するかをよく考えてから、実装すると良いかもしれません
https://gist.github.com/ndbroadbent/588fefab8e0f1b459fcec8181b41b39c
今回のアプリではジョージアの方にも見てもらいたいという意識から、ジョージア語をi18nにて導入していますが、ジョージア語の場合は下記で設定されています
[![Image from Gyazo](https://i.gyazo.com/e07ad41c190bae001217c90471d9263b.png)](https://gyazo.com/e07ad41c190bae001217c90471d9263b)
ジョージア語のデフォルト設定で必要な識別子は「ka」「ka-GE」だと確認取れますので、ジョージア語を追加するには下記のように設定します
```ruby:config/application.rb
    config.i18n.available_locales = [ :ja, :en , :ka]
```
または
```ruby:config/application.rb
    config.i18n.available_locales = [ :ja, :en , :ka-GE]
```
**ここから先はジョージア語でymlファイルを作成する形になります**

# 3.自身が実装したい言語の翻訳に対応させるためのymlを用意する
以下のコマンドを順にターミナルで実行し、rails_i18n に使用するディレクトリ、ファイルの生成をします（VSCodeでディレクトリ、ファイルを生成できれば、その方法でも構いません）
```
mkdir config/locales/views
※ディレクトリがある場合は、このコマンドはパスしてください
```
```
touch config/locales/views/ka.yml
※i18nのデフォルト設定の識別子と合っているのを確認して、ファイルの生成してください
```
# 4.自身が実装したい言語の翻訳に対応させるためのymlを記述する

ymlを以下のように記述します(一例)
ja.ymlがある場合、自分が実装したい言語と構造の差があった場合、「対応するyml情報がないよ」のエラーが出ますので、ご注意ください
```config/locales/activerecord/ka.yml
ka:
  activerecord:
    models:
      user: მომხმარებელი
      post: სამზარეულოს შეფასება
      comment: კომენტარი
    attributes:
      user:
        email: ელ
        user_name: მომხმარებლის სახელი
        password: პაროლი
        password_confirmation: პაროლის დადასტურება
      post:
        title: სათაური
        body: სხეული (წერილის)
        post_image: ატვირთეთ სურათი
        rating: რეიტინგული ვარსკვლავი
      comment:
        body: კომენტარი
```
翻訳はどうするかについてですが、
自力で訳してみる
AIツールを使う
外国人の知り合いに助けてもらう
の3者選択になります
DeepLは33もの言語に対応、(2025年2月現在)
Google 翻訳は全132言語の翻訳に対応しています（2023年7月時点）

ジョージア語のようなマイナーな言語はさすがにDeepLにのっていないので、(2025年2月現在)
Google 翻訳を使用しました
日本語からジョージア語で訳すと、訳の意味が大きくかけ離れることもあるので、
Google 翻訳を用いて他の言語(特に漢字文化圏以外)に訳す場合は、
```
日本語→英語
英語→対象の言語
```
の順で訳すと自然な訳になると考えます

下記の言語で訳す場合はDeeplを使用したほうが精度として良いと思います
```
Deeplを使用したほうが精度が良い言語
アラビア語
イタリア語
インドネシア語
ウクライナ語
エストニア語
オランダ語
ギリシャ語
スウェーデン語
スペイン語
スロバキア語
スロベニア語
デンマーク語
ドイツ語
トルコ語
ノルウェー語(ブークモール)
ハンガリー語
フィンランド語
フランス語
ポーランド語
ポルトガル語
ポルトガル語(ブラジルの)
ラトビア語
リトアニア語
ルーマニア語
ロシア語
英語(アメリカの)
英語(イギリスの)
韓国語
中国語(簡体字)
中国語(繁体字)
日本語
```
# 5.フロントサイド(view画面)に翻訳ボタンのフォームを加える
view画面に翻訳ボタンのフォームを加えます
今回はヘッダー画面に追加しています
```HTML:app/views/posts/favorites.html.erb
<--省略-->
<%= link_to 'JP', url_for(locale: :ja), class: "text-white text-xs py-2 px-2" %> /
<%= link_to 'EN', url_for(locale: :en), class: "text-white text-xs py-2 px-2" %> /
<%= link_to 'GE', url_for(locale: :ka), class: "text-white text-xs py-2 px-2" %>
<--省略-->
```
# 6.動作を確認する
翻訳漏れがないか、エラーが出ていないか確認します

[![Image from Gyazo](https://i.gyazo.com/3af199b9b27c01579474b8e9106eb996.gif)](https://gyazo.com/3af199b9b27c01579474b8e9106eb996)

[![Image from Gyazo](https://i.gyazo.com/e19803729b158298adaf943e276b832b.gif)](https://gyazo.com/e19803729b158298adaf943e276b832b)