16
9

More than 3 years have passed since last update.

【Rails】devise-i18nでscopedなビューを翻訳するワザ

Last updated at Posted at 2020-01-30

Devise を使えば、Rails アプリにユーザー登録・認証の機能を少ない工数で追加できる。筆者もよくお世話になっているgemの一つ。

Devise そのものには日本語などの翻訳は含まれていないが、devise-i18n gem を追加することで、翻訳が利用可能になる。

しかし、Devise で複数の scope(UserAdmin で分けるケースなど)を使っていると、devise-i18n で生成したビューはそのままでは translation missing になってしまう。これをうまく回避する。

translation missingの原因

たとえば、以下のコマンドでビューを生成して、

$ bin/rails g devise:i18n:views users

/users/sign_in などを見ると、以下のように(一部が)翻訳されていないことがわかる。

image.png

これは、devise-i18n で生成されるビューが、t の引数に相対指定をしているのが原因1

app/views/users/sessions/new.html.erb
<h2><%= t(".sign_in") %></h2><%# ←❗️こことか %>

<%= simple_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
  <div class="form-inputs">
    <%= f.input :email, required: false, autofocus: true %>
    <%= f.input :password, required: false %>
    <%= f.input :remember_me, as: :boolean if devise_mapping.rememberable? %>
  </div>

  <div class="form-actions">
    <%= f.button :submit, t(".sign_in") %><%# ←❗️このあたり %>
  </div>
<% end %>

<%= render "users/shared/links" %>

これをなんとかしたい。

解決策

採れうる策は2つある。

  1. t の引数を、相対指定から絶対指定にすべて書き換える
  2. 翻訳の YAML に、当該のビューに対応するキーを追加して、その下に一通りの翻訳をコピーする

1.は書き換えるファイルが多く面倒だし、せっかく自動生成しているメリットをあまり生かせない。2.は単純にコピーすると二重管理になってしまって良くないが、YAML のアンカーとエイリアスを使えば回避できる。今回は2.の方法を使う。

※ YAML のアンカーとエイリアスについては、この記事などが詳しい: プログラマーのための YAML 入門 (初級編)

エイリアスで翻訳を共有

まず、以下のコマンドで翻訳ファイルを生成する。

$ bin/rails g devise:i18n:locale ja

config/locales/devise.views.ja.yml に翻訳ファイルが生成されるので、このファイルを以下のように変更する。

config/locales/devise.views.ja.yml
ja:
  activerecord:
    attributes:
      user:
        confirmation_sent_at: パスワード確認送信時刻

  # ...(略)...

    models:
      user: ユーザ
  devise: &devise # ←❗️①
    confirmations:
      confirmed: メールアドレスが確認できました。

  # ...(略)...

  users: *devise # ←❗️②
  admins: *devise # ← ❗️②

① まず、生成された翻訳ファイルの devise というキーに YAML のアンカーを設定する。アンカーは & 記号を使う。

  devise: &devise

② 次に、ファイルの末尾あたりに、スコープと同名のキー(例: User モデルなら usersAdmin なら admins)をそれぞれ作り、先程のアンカーをエイリアスで参照する。エイリアスは * 記号を使う。

  # インデントはdevise:と同じレベルに合わせる
  users: *devise
  admins: *devise

もしスコープが増えたら、同じようにキーとエイリアスを追加する。

これで、翻訳されるようになる:tada:

image.png


  1. たとえばこのケースであれば、ビューのファイルが位置するusers/sessions/ディレクトリを元に、users.sessions.sign_inというキーの翻訳を探しにいく。 

16
9
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
16
9