这发生在我的 Rails 应用程序中,但我不确定这是否是 Rails 的问题,或者我是否误解了多部分表单应该如何工作。
这是(类似于)我的表格:
<%= form_for @user do |f| %>
<%= f.text_field :name %>
<%= f.submit %>
<% end %>
User#name
有一个存在验证。如果我访问users/1/edit
,清空“名称”文本字段的值,然后单击提交,由于存在验证失败,没有任何更新。到现在为止还挺好。
但是现在我已经avatar
向我的用户添加了一个属性(使用 Paperclip gem 进行文件存储),所以我相应地更新了表单:
<%= form_for @user do |f| %>
<%= f.text_field :name %>
<%= f.file_field :avatar %>
<%= f.submit %>
<% end %>
现在,如果我去编辑用户并为 提交一个空白值name
,验证不会失败。User#name
保持它以前的值,但更新似乎仍然成功(即我没有收到有关失败验证的错误消息并且updated_at
数据库中的时间戳得到更新。)
经过仔细检查,似乎当我file_field
在表单中包含 a 时,它会在提交空白文本字段时改变表单的行为(可能是由于form_for
现在输出带有 的表单enctype=-"multipart/form-data"
)。
当file_field
不存在时,提交空白name
会将这些参数发送到服务器:
{ "id" => 1, "user" => { "name: "" }
这会导致类似于User.find(1).update_attributes(name: "")
控制器中的内容,当然无法更新,因为 Rails 看到我们正在尝试将“名称”更新为空白字符串并且验证失败。
当它存在时,它会被提交:
{ "id" => 1, "user" => { }
(加上关于头像文件的额外信息)
“名称”键根本不存在,因此控制器运行User.find(1).update_attributes()
当然会通过,因为没有任何更新可能导致验证失败。
这是一个错误,还是一个功能?为什么将 enctype 更改为 multipart(假设这是问题的根源)会改变空白文本字段的行为方式?(我已经在 Chrome 和 FF 中对此进行了测试,fwiw。)如果这确实是预期的行为,我如何确保正确提交空白文本字段而不必在每个文本字段周围添加一堆乏味的样板?
(如果重要的话,我正在使用:Ruby 2.3.0、Rails 5.0.0.beta3、Paperclip 5.0.0.beta1,并且我已经在 Chrome 49 和 Firefox 45 中进行了测试)