Edited at

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 初めて使った。