在Rails 4中使用作用域路由的默认值始终会覆盖default_url_options

时间:2015-02-20 15:14:12

标签: ruby-on-rails routes scope

我正在尝试在现有应用中的网址中实现可选“region”参数:

现有: /博客

新: / SE /博客 要么 / EN /博客

这条路线应该是可选的(它只能用作过滤器,没有区域意味着全世界),参数值应该是'ww'(全世界)或nil(或者其他什么,只要我知道没有提供)。

我提出的路线如下:

scope "(:region)", region: /en|se|dk|no|ww/, defaults: {region: 'ww'} 

我在ApplicationController中使用default_url_options将:region参数设置为与param [:region]相同,以便在它存在时保留它并且应该添加到页面上的所有URL中。

def default_url_options(options={})
  { region: params[:region] }
end

问题在于,当我使用url / se / blogs时,参数被正确设置为'se',但它没有自动添加到页面上的任何URL。如果我删除了作用域路由的默认值选项,并预先设置参数'se'但是,因为没有默认值,许多网址失败,出现'ActionController :: UrlGenerationError:No route matches',因为在url helper中对象正在取区域值,因为没有默认值。

关于如何解决这个问题的任何想法?它可能与这个(尚未解决的)问题有关吗? https://github.com/rails/rails/issues/12178

2 个答案:

答案 0 :(得分:3)

设置默认区域的方式似乎不起作用;但是,根据指南,它应该:

http://guides.rubyonrails.org/routing.html#defining-defaults

如果nil是可接受的值,为什么不删除默认值?

<强>配置/ routes.rb中

scope "(:region)", region: /en|se|dk|no|ww/ do
  resources :blogs
end

作为解决方法,您可以设置默认区域,如下所示:

应用/控制器/ application_controller.rb

def default_url_options(options={})
  { region: params[:region] || "ww" }
end

<强>更新

没有默认区域:

<强>配置/ routes.rb中

scope "(:region)", region: /en|se|dk|no/ do
  resources :blogs do
    resources :posts
  end
end

应用/控制器/ application_controller.rb

def default_url_options(options={})
  { region: params[:region] }
end

在您看来:

<% @blog.posts.each do |post|
  <%= link_to post.title, blog_post_path(@blog, post) %>
<% end %>

未指定地区时的网址:

/blogs/1/posts/1

指定en区域时的网址:

/en/blogs/1/posts/1

更新#2:

好的,我能够重现你的失败测试。这是由Rails错误引起的,它与您在问题中提到的错误相同。您可以在此处详细了解该问题和一些解决方法:

https://github.com/rspec/rspec-rails/issues/255

要通过测试,一种方法是使用region块初始化default_url_options中的before(:all)选项。尝试将以下内容添加到RSpec配置中:

<强>规格/ rails_helper.rb

RSpec.configure do |config|
  config.before(:each) do
    default_url_options[:region] = nil
  end
end

您可能希望将该区块限制为featurecontroller组类型。

希望有所帮助。

答案 1 :(得分:0)

我希望保留现有路线/blogs,只需添加一个名为region的可选参数。

所以网址就像/blogs?region=se/blogs?region=en

然后在您的controller中,您只需根据params[:region]

应用不同的代码

更简单,更稳定的网址结构。