diff options
author | James Coleman <jtc331@gmail.com> | 2014-09-23 20:38:23 -0400 |
---|---|---|
committer | James Coleman <jtc331@gmail.com> | 2016-02-19 11:09:15 -0500 |
commit | 459cd7fdd1aad97863f4dda0a385b422b70b9e9b (patch) | |
tree | 647aa258c6a0dcb2dc2d409239cfd6ee40498905 /actionview/lib/action_view/helpers | |
parent | 73fb2977cab8cd9b8ed7bb61df3072e2ca74b3ce (diff) | |
download | rails-459cd7fdd1aad97863f4dda0a385b422b70b9e9b.tar.gz rails-459cd7fdd1aad97863f4dda0a385b422b70b9e9b.tar.bz2 rails-459cd7fdd1aad97863f4dda0a385b422b70b9e9b.zip |
Fix button_to's params option to support nested names.
In e6e0579defcfcf94ef1c4c1c7659f374a5335cdb the `params` option was added to the `button_to` helper. However, the patch doesn't support nested hashes so `{a: {b: 'c'}}` for example gets turned into a hidden form input with the name 'a' and the value being the string representation of the `{b: 'c'}` nested hash.
Since Rails supports nested hashes everywhere else (and even in the URL params of link_to and button_to), I believe this to be a bug/unfinished feature.
Diffstat (limited to 'actionview/lib/action_view/helpers')
-rw-r--r-- | actionview/lib/action_view/helpers/url_helper.rb | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/actionview/lib/action_view/helpers/url_helper.rb b/actionview/lib/action_view/helpers/url_helper.rb index 3a4561a083..87218821ed 100644 --- a/actionview/lib/action_view/helpers/url_helper.rb +++ b/actionview/lib/action_view/helpers/url_helper.rb @@ -329,8 +329,8 @@ module ActionView inner_tags = method_tag.safe_concat(button).safe_concat(request_token_tag) if params - params.each do |param_name, value| - inner_tags.safe_concat tag(:input, type: "hidden", name: param_name, value: value.to_param) + to_form_params(params).each do |param| + inner_tags.safe_concat tag(:input, type: "hidden", name: param[:name], value: param[:value]) end end content_tag('form', inner_tags, form_options) @@ -595,6 +595,42 @@ module ActionView def method_tag(method) tag('input', type: 'hidden', name: '_method', value: method.to_s) end + + # Returns an array of hashes each containing :name and :value keys + # suitable for use as the names and values of form input fields: + # + # to_form_params(name: 'David', nationality: 'Danish') + # # => [{name: :name, value: 'David'}, {name: 'nationality', value: 'Danish'}] + # + # to_form_params(country: {name: 'Denmark'}) + # # => [{name: 'country[name]', value: 'Denmark'}] + # + # to_form_params(countries: ['Denmark', 'Sweden']}) + # # => [{name: 'countries[]', value: 'Denmark'}, {name: 'countries[]', value: 'Sweden'}] + # + # An optional namespace can be passed to enclose key names: + # + # to_form_params({ name: 'Denmark' }, 'country') + # # => [{name: 'country[name]', value: 'Denmark'}] + def to_form_params(attribute, namespace = nil) # :nodoc: + params = [] + case attribute + when Hash + attribute.each do |key, value| + prefix = namespace ? "#{namespace}[#{key}]" : key + params.push(*to_form_params(value, prefix)) + end + when Array + array_prefix = "#{namespace}[]" + attribute.each do |value| + params.push(*to_form_params(value, array_prefix)) + end + else + params << { name: namespace, value: attribute.to_param } + end + + params.sort_by { |pair| pair[:name] } + end end end end |