From 00b26532f05283d2b160308522d1bd2146d6ac18 Mon Sep 17 00:00:00 2001 From: Mauro George Date: Mon, 8 Dec 2014 20:22:36 -0200 Subject: Add a hidden_field on the file_field This will avoid a error be raised when the only input on the form is the `file_field`. --- actionview/lib/action_view/helpers/form_helper.rb | 17 +++++++++++++++++ actionview/lib/action_view/helpers/tags/file_field.rb | 13 +++++++++++++ 2 files changed, 30 insertions(+) (limited to 'actionview/lib/action_view') diff --git a/actionview/lib/action_view/helpers/form_helper.rb b/actionview/lib/action_view/helpers/form_helper.rb index c4371dc705..e3a8f998a8 100644 --- a/actionview/lib/action_view/helpers/form_helper.rb +++ b/actionview/lib/action_view/helpers/form_helper.rb @@ -854,6 +854,23 @@ module ActionView # # file_field(:attachment, :file, class: 'file_input') # # => + # + # ==== Gotcha + # + # The HTML specification says when nothing is select on a file field web browsers do not send any value to server. + # Unfortunately this introduces a gotcha: + # if an +User+ model has a +avatar+ field, and in the form none file is selected no +avatar+ parameter is sent. So, + # any mass-assignment idiom like + # + # @user.update(params[:user]) + # + # wouldn't update avatar. + # + # To prevent this the helper generates an auxiliary hidden field before + # every file field. The hidden field has the same name as file field and blank value. + # + # In case if you don't want the helper to generate this hidden field you can specify + # include_hidden: false option. def file_field(object_name, method, options = {}) Tags::FileField.new(object_name, method, self, options).render end diff --git a/actionview/lib/action_view/helpers/tags/file_field.rb b/actionview/lib/action_view/helpers/tags/file_field.rb index 476b820d84..02585fa0ae 100644 --- a/actionview/lib/action_view/helpers/tags/file_field.rb +++ b/actionview/lib/action_view/helpers/tags/file_field.rb @@ -2,6 +2,19 @@ module ActionView module Helpers module Tags # :nodoc: class FileField < TextField # :nodoc: + + def render + options = @options.stringify_keys + if options.fetch("include_hidden", true) + add_default_name_and_id(options) + options[:type] = "file" + tag("input", :name => options["name"], :type => "hidden", :value => "") + tag("input", options) + else + options.delete("include_hidden") + @options = options + super + end + end end end end -- cgit v1.2.3