Rails I18n+Turbo Streams:如何让Turbo Streams适配当前语言区域?
解决Rails Turbo Streams渲染时Locale不生效的问题
问题根源
你当前在模型中调用broadcast_render_to时,代码是在模型上下文执行的,并没有经过控制器的around_action :switch_locale回调。这就导致I18n没有切换到用户当前设置的locale,始终使用默认值渲染内容。
解决方案
方案1:在控制器中触发广播(推荐)
将广播逻辑从模型的after_save回调转移到控制器的action中,这样就能利用控制器已有的locale上下文:
- 移除模型中的
after_save回调:
# engines/my_engine/app/models/personal_data.rb # 删掉原来的after_save广播代码
- 在对应的控制器action中添加广播:
# engines/my_engine/app/controllers/personal_data_controller.rb def update @personal_data = PersonalData.find(params[:id]) if @personal_data.update(personal_data_params) # 这里处于switch_locale的上下文内,locale已正确设置 @personal_data.broadcast_render_to( "personal_data:#{@personal_data.id}", partial: "personal_data_display", locals: { personal_data: @personal_data } ) end # 其他响应逻辑... end
方案2:在模型广播时手动指定locale
如果必须保留模型中的after_save回调,可以通过关联用户的locale字段(需提前将用户偏好locale存储到数据库),手动包裹广播逻辑:
# engines/my_engine/app/models/personal_data.rb after_save do # 假设PersonalData关联了User模型,且User有locale字段 target_locale = user.locale || I18n.default_locale I18n.with_locale(target_locale) do broadcast_render_to( "personal_data:#{id}", partial: "personal_data_display", locals: { personal_data: self } ) end end
方案3:自定义Turbo Stream控制器
创建继承自ApplicationController的专属控制器,利用其switch_locale回调处理locale,然后让模型广播指向该控制器的action:
- 创建Turbo Stream控制器:
# app/controllers/turbo_streams_controller.rb class TurboStreamsController < ApplicationController around_action :switch_locale def personal_data_update @personal_data = PersonalData.find(params[:id]) render turbo_stream: turbo_stream.replace( "target-personal-data-display", partial: "my_engine_1/personal_data/personal_data_display", locals: { personal_data: @personal_data } ) end end
- 更新模型的广播逻辑:
# engines/my_engine/app/models/personal_data.rb after_save do broadcast_action_to( "personal_data:#{id}", action: :replace, target: "target-personal-data-display", controller: "turbo_streams", action_name: "personal_data_update", id: id ) end
- 添加路由:
# config/routes.rb resources :turbo_streams, only: [] do get :personal_data_update, on: :collection end
内容的提问来源于stack exchange,提问作者pabvald
相关产品推荐
相关产品推荐

