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
解决办法
调整参数允许的执行顺序
switch_locale作为around_action,执行优先级高于普通before_action。修改ApplicationController中的before_action配置,让参数允许逻辑提前执行:before_action :permit_additional_params, prepend: true这样
permit_additional_params会在所有其他回调之前运行,确保params[:locale]被提前允许。直接在参数读取前允许
在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这种方式直接在使用参数的位置完成允许,避免顺序问题。
排查数据库NLS配置
错误指向数据库会话修改语句,虽然提示是参数问题,但可能数据库切换后THAI_M排序规则不被支持。暂时注释该行测试,如果错误消失,需确认当前数据库的可用排序规则并替换。验证全局参数过滤设置
检查config/application.rb中的参数配置,确保没有全局覆盖:config.action_controller.permit_all_parameters = false # 保持默认false即可
内容的提问来源于stack exchange,提问作者the invincible
相关产品推荐
相关产品推荐

