This is happening in my Rails app, but I'm not sure whether this is an issue with Rails or if I'm misunderstanding how multipart forms are supposed to work.
Here's (something like) my form:
<%= form_for @user do |f| %>
<%= f.text_field :name %>
<%= f.submit %>
<% end %>
User#name
has a presence validation. If I visit users/1/edit
, empty out the value of the 'name' text field, and click submit, nothing gets updated because the presence validation fails. So far, so good.
But now I've added an avatar
attribute to my User (using the Paperclip gem for file storage), so I update the form accordingly:
<%= form_for @user do |f| %>
<%= f.text_field :name %>
<%= f.file_field :avatar %>
<%= f.submit %>
<% end %>
Now, if I go to edit the user and submit a blank value for name
, the validation doesn't fail. User#name
keeps it previous value, but the update still appears to be successful (i.e. I don't get an error message about failed validations and the updated_at
timestamp in the database gets updated.)
On closer inspection, it seems that when I include a file_field
in the form, it changes the form's behaviour when submitting blank text fields (probably due to the fact that form_for
now outputs a form with enctype=-"multipart/form-data"
).
When the file_field
isn't present, submitting a blank name
sends these params to the server:
{ "id" => 1, "user" => { "name: "" }
Which results in something like User.find(1).update_attributes(name: "")
in the controller, which of course fails to update because Rails sees that we're trying to update 'name' to a blank string and the validation fails.
When it is present, this gets submitted:
{ "id" => 1, "user" => { }
(plus extra info about the avatar file)
The "name" key isn't present at all, so the controller runs User.find(1).update_attributes()
which of course passes as there's nothing being updated that might fail a validation.
Is this a bug, or a feature? Why would changing the enctype to multipart (assuming that's the source of the problem) change the way blank text fields behave? (I've tested this in both Chrome and FF, fwiw.) If this is really the intended behaviour, how can I ensure that blank text fields get submitted properly without having to add a bunch of tedious boilerplate around every text field?
(If it matters, I'm using: Ruby 2.3.0, Rails 5.0.0.beta3, Paperclip 5.0.0.beta1, and I've tested in Chrome 49 and Firefox 45)
I had the same issue, updating Rails to the latest version fixed it.