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

React on Rails中Unpermitted parameter: :locale错误求助

React on Rails 项目中 Unpermitted parameter: :locale 错误排查与解决

错误信息

error
'  ↳ app/controllers/concerns/set_locale.rb:35:in `switch_locale'
Unpermitted parameter: :locale'

背景说明

近期更换数据库后出现该错误,已尝试添加params.permit(:locale)但未解决。使用版本:Rails v6.0.3.6、Ruby v2.7.2、Bundler 2.1.4。

相关代码

set_locale.rb

module SetLocale
  extend ActiveSupport::Concern

  included do
    around_action :switch_locale
    helper_method :current_locale
    helper_method :switch_locale_urls
  end

  def current_locale
    extract_locale.presence || I18n.default_locale
  end

  def switch_locale_urls
    locale_regex = %r{^/(#{I18n.available_locales.join('|')})/}i

    I18n.available_locales.index_with do |locale|
      if request.method == 'GET' && original_fullpath.match(locale_regex)
        original_fullpath.gsub(locale_regex, "/#{locale}/")
      else
        root_path(locale: locale)
      end
    end.to_h
  end

  protected def original_fullpath
    request.original_fullpath
  end

  private def switch_locale(&action)
    locale = extract_locale || I18n.default_locale
    response.set_header('Content-Language', locale.to_s)
    ActiveRecord::Base.connection.execute("alter session set nls_sort = 'THAI_M'") # 错误指向此行
    I18n.with_locale(locale, &action)
  end

  private def extract_locale
    parsed_locale = params[:locale]
    I18n.available_locales.map(&:to_s).include?(parsed_locale) ? parsed_locale : nil
  end

  private def default_url_options
    { locale: I18n.locale }
  end
end

ApplicationController.rb

class ApplicationController < ActionController::Base
  include BasicAuthProtection
  include CurrentUserSession
  include ErrorPages
  include SetLocale
  include Pagination

  helper VimeoHelper
  helper SVGHelper
  helper ChunksHelper

  protect_from_forgery
  per_request_react_rails_prerenderer

  before_action :permit_additional_params
  before_action :add_ssr_variables, :store_location

  
  def store_location
    unless request.path.include?('session')
      session[:previous_url] = request.fullpath
    end
  end
  
  # Permit the locale parameter globally
  protected def permit_locale_param
    params.permit(:locale)
  end
  
  # rubocop:disable Rails/OutputSafety
  protected def add_ssr_variables
    react_rails_prerenderer
    .context
      .exec("global.I18N_LOCALE = #{I18n.locale.to_json.html_safe}")
      react_rails_prerenderer
      .context
      .exec("global.FORM_AUTHENTICITY_TOKEN = #{form_authenticity_token.to_json.html_safe}")
    end
    # rubocop:enable all
    private
  
    def permit_additional_params
      # Permit the locale and other custom params
      params.permit(:locale, :page, :per_page, :sort, filters: { cuisine: [], dish_type: [], main_ingredient: [] })
    end
  end

解决办法

  1. 调整参数允许的执行顺序
    switch_locale作为around_action,执行优先级高于普通before_action。修改ApplicationController中的before_action配置,让参数允许逻辑提前执行:

    before_action :permit_additional_params, prepend: true
    

    这样permit_additional_params会在所有其他回调之前运行,确保params[:locale]被提前允许。

  2. 直接在参数读取前允许
    在extract_locale方法中,先执行参数允许再读取值:

    private def extract_locale
      params.permit(:locale)
      parsed_locale = params[:locale]
      I18n.available_locales.map(&:to_s).include?(parsed_locale) ? parsed_locale : nil
    end
    

    这种方式直接在使用参数的位置完成允许,避免顺序问题。

  3. 排查数据库NLS配置
    错误指向数据库会话修改语句,虽然提示是参数问题,但可能数据库切换后THAI_M排序规则不被支持。暂时注释该行测试,如果错误消失,需确认当前数据库的可用排序规则并替换。

  4. 验证全局参数过滤设置
    检查config/application.rb中的参数配置,确保没有全局覆盖:

    config.action_controller.permit_all_parameters = false # 保持默认false即可
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 02:37:05