Help us understand the problem. What is going on with this article?

RailsでI18n.localeを書き換えていたらたまに言語設定がバグる問題に遭遇した

RailsでI18n.localeを書き換えてたらたまに言語設定がバグる問題に遭遇した

他のユーザー(:en)で画面を参照したあとに元のユーザー(:ja)で画面を見ると、稀にlocale=:enで画面が表示されてしまうという問題に遭遇しました。

実装はこんな感じ。

class HogeController < ApplicationController
  before_action :set_locale

  def set_locale
    I18n.locale = current_user.locale || I18n.default_locale
  end
end

https://railsguides.jp/i18n.html#リクエスト間でロケールを管理する

Railsガイドでもだいたいおんなじ感じのコードが乗ってる。ApplicationControllerに書いて全コントローラーに継承させるのならこれでもいけるんですが、継承されないコントローラーにアクセスした場合に他のユーザーが設定したロケールになってしまう事があった。

https://github.com/rails/rails/pull/34356

こんなPull RequestもありI18nはスレッドセーフだと言っていますが、
スレッドセーフなだけで、after_actionとかで元の言語に戻しておいてあげないと次に同じスレッドを使ったときに変更されたままの言語が使われてしまうといった感じなんだと思われます。
(違うコントローラーなどでset_localeが実行されない場合に起こる)

こんなふうに実装を変えたら解消しました。

class HogeController < ApplicationController
  around_action :set_locale

  def set_locale
    locale = current_user.locale || I18n.default_locale
    I18n.with_locale locale do
      yield
    end
  end
end

I18n.with_locale を使うことにより、ロケールの変更をアクション実行時に限定しました。
after_action でもとに戻すでも行けると思いますが、こっちのほうがドヤり感が高い。

around_action 初めて使った。

shwld
主に開発で得られた知見を記録していきます。 記載された内容は、所属する企業や団体の公式見解ではありません。
https://shwld.net
mof-mof
「つくって人をしあわせにする」をビジョンにAIチャットボットや開発チームレンタル等のサービスを提供している渋谷のIT企業です
https://www.mof-mof.co.jp/about
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away