带有参数`params`的`url_for`的奇怪行为

时间:2015-02-07 02:35:36

标签: ruby-on-rails ruby ruby-on-rails-4 params url-for

我正在使用Ruby 2.1.1和Ruby on Rails 4.1.1。

...鉴于

...我访问了网址

http://www.example.org/users/1/ciao/edit?hash[controller]=articles&hash[action]=index

...在呈现的编辑视图中,在表单中,我有:

<% hash[:hash].each do |key, value| %>
  <%= hidden_field_tag("hash[#{key}]", value) %>
<% end %>

...在我的控制器中我有:

logger.debug "params        => #{params.inspect}" 
logger.debug "params[:hash] => #{params[:hash].inspect}" 

url_for(params[:hash].merge(:only_path => true))

当我提交表单时,通过记录,我得到:

params        => { "hash" => { "controller" => "articles", "action" => "index" }, "user_id" => "1", "controller" => "users/ciao", "action" => "update", "users_ciao" => { "language"=>"it" }, "_method" => "patch", "commit" => "Update", "utf8" => "✓"}
params[:hash] => { "controller" => "articles", "action" => "index" }

ActionController::UrlGenerationError (No route matches { :controller => "users/articles", :action => "show", :user_id => "1"}):

url_for我通过了params[:hash] { "controller" => "articles", "action" => "show" },对吧?为什么我获得:controller => "users/articles"和添加的:user_id => "1"?!这是一个错误吗?

奇怪的行为与自动命名空间有关:当我检查params[:hash]时,它是{ "controller" => "articles", "action" => "index" }但是当我将其传递给url_for方法时,它变为{ :controller => "users/articles", :action => "show", :user_id => "1"}


注意:嵌套资源不会出现此问题。也就是说,例如,当初始URL是as-like

http://www.example.org/users/1/edit?hash[controller]=articles&hash[action]=index

通过查看ActionDispatch::Routing::UrlFor#url_for源代码,当reverse_merge!(url_options)options时,我看到它会运行Hash

经过深入思考后,我提出了以下代码(似乎按预期工作),以便跳过reverse_merge!(url_options)

_routes.url_for(params[:hash].merge(:only_path => true).symbolize_keys)

而不是使用:

url_for(params[:hash].merge(:only_path => true))

即使使用Ruby on Rails 4.2.0也会发生这种情况。

1 个答案:

答案 0 :(得分:0)

url_for会自动提示控制器的命名空间,除非它是绝对的,所以如果你不需要user命名空间,那么你可以写:

controller: '/articles'