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

Rails中default_url_options与路径/url辅助方法参数冲突如何解决?

Rails 6.1 搭配 routing-filter locale 过滤器传参报错解决方案

问题表现

在Rails 6.1.4应用中引入routing-filter Gem的locale过滤器实现URL带语言前缀(如/en/articles)后,路径辅助方法传入params或其他可选参数时会触发路由匹配错误,无额外参数时调用完全正常。

复现代码

# test/controllers/articles_controller_test.rb
patch article_url(@article, params: { article: my_hash })

错误信息

# Error output
ArticlesControllerTest#test_should_update:
DRb::DRbRemoteError: No route matches {:action=>"show", :controller=>"articles",
 :locale=>#<Article id: 805413029, ...>}, missing required keys: [:id]
 (ActionController::UrlGenerationError)
    test/controllers/articles_controller_test.rb:58:in `block in <class:ArticlesControllerTest>'

错误原因是路径辅助方法将传入的模型实例@article错误识别为locale参数值,导致路由缺少必填的id参数。

原有配置

# test_helper.rb  (routing-filter参考文档推荐配置)
RoutingFilter.active = false

# application_controller.rb
def default_url_options
  Rails.application.default_url_options = Rails.application.routes.default_url_options =
   { locale: I18n.locale }
end

# config/routes.rb
Rails.application.routes.draw do
  filter :locale
  
  scope "(:locale)", locale: /en|ja|fr/ do # 该scope可删除,多余配置有时会导致路径中的locale重复,引发问题
    resources :articles
  end
end

注意:当前使用的是routing-filter主分支最新提交(8d1f1da),RubyGems发布的0.6.3版本已知不兼容Rails 6.1。

解决方案

第一步:移除路由冗余配置

首先删除routes.rb中包裹资源的(:locale) scope,routing-filter的locale过滤器会自动处理路径前缀,不需要额外手动声明scope,重复配置会干扰参数解析逻辑。

第二步:修正default_url_options赋值逻辑

ApplicationController中的default_url_options不需要每次调用都覆盖全局配置,调整为如下写法即可,保证默认参数可以被路径辅助方法正常识别:

# application_controller.rb
def default_url_options
  { locale: I18n.locale }
end

第三步:测试环境配置调整

测试环境中默认不会自动加载控制器的default_url_options,在test_helper.rb中添加如下配置,让测试环境的路径辅助方法也能自动带上locale参数:

# test_helper.rb
class ActionDispatch::IntegrationTest
  def default_url_options
    { locale: I18n.default_locale } # 可根据测试需求指定对应locale
  end
end

调整完成后所有路径辅助方法都可以正常传参,不需要手动合并default_url_options,原有的调用代码patch article_url(@article, params: { article: my_hash })可以直接正常运行。

临时替代方案(如暂时无法修改全局配置)

如果因为项目限制无法调整全局配置,可以在路径辅助方法中先显式传入locale参数,避免模型被识别为locale值:

article_url(locale: I18n.locale, id: @article, params: { article: my_hash })

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 08:21:00