aboutsummaryrefslogtreecommitdiffstats
path: root/actionview/lib/action_view/helpers/url_helper.rb
diff options
context:
space:
mode:
authorJames Coleman <jtc331@gmail.com>2014-09-23 20:38:23 -0400
committerJames Coleman <jtc331@gmail.com>2016-02-19 11:09:15 -0500
commit459cd7fdd1aad97863f4dda0a385b422b70b9e9b (patch)
tree647aa258c6a0dcb2dc2d409239cfd6ee40498905 /actionview/lib/action_view/helpers/url_helper.rb
parent73fb2977cab8cd9b8ed7bb61df3072e2ca74b3ce (diff)
downloadrails-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/url_helper.rb')
-rw-r--r--actionview/lib/action_view/helpers/url_helper.rb40
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