You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails I18n+Turbo Streams:如何让Turbo Streams适配当前语言区域?

解决Rails Turbo Streams渲染时Locale不生效的问题

问题根源

你当前在模型中调用broadcast_render_to时,代码是在模型上下文执行的,并没有经过控制器的around_action :switch_locale回调。这就导致I18n没有切换到用户当前设置的locale,始终使用默认值渲染内容。

解决方案

方案1:在控制器中触发广播(推荐)

将广播逻辑从模型的after_save回调转移到控制器的action中,这样就能利用控制器已有的locale上下文:

  1. 移除模型中的after_save回调:
# engines/my_engine/app/models/personal_data.rb
# 删掉原来的after_save广播代码
  1. 在对应的控制器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:

  1. 创建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
  1. 更新模型的广播逻辑:
# 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
  1. 添加路由:
# config/routes.rb
resources :turbo_streams, only: [] do
  get :personal_data_update, on: :collection
end

内容的提问来源于stack exchange,提问作者pabvald

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 00:48:28