我正在尝试在现有应用中的网址中实现可选“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
答案 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
您可能希望将该区块限制为feature
和controller
组类型。
希望有所帮助。
答案 1 :(得分:0)
我希望保留现有路线/blogs
,只需添加一个名为region
的可选参数。
所以网址就像/blogs?region=se
或/blogs?region=en
然后在您的controller
中,您只需根据params[:region]
更简单,更稳定的网址结构。