在 Rails 4 中使用范围路由的默认值总是覆盖 default_url_options
Using defaults values for scoped route in Rails 4 always overrides default_url_options
我正在尝试在现有应用程序的 url 中实现 可选 "region" 参数:
现有:
/博客
新:
/se/blogs
或者
/en/blogs
这条路线应该是可选的(它只会用作过滤器,没有区域意味着世界范围内),参数值应该是 'ww' (世界范围内)或 nil (或其他任何东西,如只要我知道 none 已提供)。
我想出的路线是这样的:
scope "(:region)", region: /en|se|dk|no|ww/, defaults: {region: 'ww'}
我在 ApplicationController 中使用 default_url_options 将 :region 参数设置为与 param[:region] 相同,以便它在存在时被保留并且应该添加到所有 urls在页面上。
def default_url_options(options={})
{ region: params[:region] }
end
问题是,当我使用 url /se/blogs 时,参数被正确设置为 'se' 但它没有被添加到页面上的任何 url自动地。如果我删除作用域路由的默认选项,它会工作并在参数前面加上参数 'se' 但是随后,因为没有默认值,许多 urls 失败并显示 'ActionController::UrlGenerationError: No route matches' 因为在 url helper 对象正在获取区域值,因为没有默认值。
关于如何解决这个问题有什么想法吗?它可能与这个(仍未解决的)问题有关吗?
https://github.com/rails/rails/issues/12178
我希望保留您现有的路线 /blogs
,并添加一个名为 region
或其他名称的可选参数。
所以 url 就像 /blogs?region=se
或 /blogs?region=en
然后在您的 controller
中,您只需要根据 params[:region]
应用不同的代码
更简单,更稳定的 url 结构。
以这种方式设置默认区域似乎不起作用;但是,根据指南,它应该:
http://guides.rubyonrails.org/routing.html#defining-defaults
如果 nil
是可接受的值,为什么不放弃默认值?
config/routes.rb
scope "(:region)", region: /en|se|dk|no|ww/ do
resources :blogs
end
作为解决方法,您可以像这样设置默认区域:
app/controllers/application_controller.rb
def default_url_options(options={})
{ region: params[:region] || "ww" }
end
更新:
没有默认区域:
config/routes.rb
scope "(:region)", region: /en|se|dk|no/ do
resources :blogs do
resources :posts
end
end
app/controllers/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 %>
URL 未指定区域时:
/blogs/1/posts/1
URL 当指定 en
区域时:
/en/blogs/1/posts/1
更新#2:
好的,我能够重现您的失败测试。这是由 Rails 错误引起的,它与您在问题中提到的错误相同。您可以在此处阅读有关此问题和一些解决方法的更多信息:
https://github.com/rspec/rspec-rails/issues/255
为了让您的测试通过,一种方法是使用 before(:all)
块初始化 default_url_options
中的 region
选项。尝试将以下内容添加到您的 RSpec 配置中:
spec/rails_helper.rb
RSpec.configure do |config|
config.before(:each) do
default_url_options[:region] = nil
end
end
您可能希望将该块限制为 feature
和 controller
组类型。
希望对您有所帮助。
我正在尝试在现有应用程序的 url 中实现 可选 "region" 参数:
现有: /博客
新: /se/blogs 或者 /en/blogs
这条路线应该是可选的(它只会用作过滤器,没有区域意味着世界范围内),参数值应该是 'ww' (世界范围内)或 nil (或其他任何东西,如只要我知道 none 已提供)。
我想出的路线是这样的:
scope "(:region)", region: /en|se|dk|no|ww/, defaults: {region: 'ww'}
我在 ApplicationController 中使用 default_url_options 将 :region 参数设置为与 param[:region] 相同,以便它在存在时被保留并且应该添加到所有 urls在页面上。
def default_url_options(options={})
{ region: params[:region] }
end
问题是,当我使用 url /se/blogs 时,参数被正确设置为 'se' 但它没有被添加到页面上的任何 url自动地。如果我删除作用域路由的默认选项,它会工作并在参数前面加上参数 'se' 但是随后,因为没有默认值,许多 urls 失败并显示 'ActionController::UrlGenerationError: No route matches' 因为在 url helper 对象正在获取区域值,因为没有默认值。
关于如何解决这个问题有什么想法吗?它可能与这个(仍未解决的)问题有关吗? https://github.com/rails/rails/issues/12178
我希望保留您现有的路线 /blogs
,并添加一个名为 region
或其他名称的可选参数。
所以 url 就像 /blogs?region=se
或 /blogs?region=en
然后在您的 controller
中,您只需要根据 params[:region]
更简单,更稳定的 url 结构。
以这种方式设置默认区域似乎不起作用;但是,根据指南,它应该:
http://guides.rubyonrails.org/routing.html#defining-defaults
如果 nil
是可接受的值,为什么不放弃默认值?
config/routes.rb
scope "(:region)", region: /en|se|dk|no|ww/ do
resources :blogs
end
作为解决方法,您可以像这样设置默认区域:
app/controllers/application_controller.rb
def default_url_options(options={})
{ region: params[:region] || "ww" }
end
更新:
没有默认区域:
config/routes.rb
scope "(:region)", region: /en|se|dk|no/ do
resources :blogs do
resources :posts
end
end
app/controllers/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 %>
URL 未指定区域时:
/blogs/1/posts/1
URL 当指定 en
区域时:
/en/blogs/1/posts/1
更新#2:
好的,我能够重现您的失败测试。这是由 Rails 错误引起的,它与您在问题中提到的错误相同。您可以在此处阅读有关此问题和一些解决方法的更多信息:
https://github.com/rspec/rspec-rails/issues/255
为了让您的测试通过,一种方法是使用 before(:all)
块初始化 default_url_options
中的 region
选项。尝试将以下内容添加到您的 RSpec 配置中:
spec/rails_helper.rb
RSpec.configure do |config|
config.before(:each) do
default_url_options[:region] = nil
end
end
您可能希望将该块限制为 feature
和 controller
组类型。
希望对您有所帮助。