我对这里提供的其他解决方案采取了完全不同的方法,因为我不喜欢切换到 CarrierWave 或使用另一个 gem 来实施破解来解决这个问题。
基本上,我为验证错误消息定义占位符,然后对相关控制器进行 AJAX 调用。如果验证失败,我只需填充错误消息占位符 - 这会将所有内容保留在客户端,包括准备重新提交的文件输入。
示例如下,展示了具有嵌套地址模型和嵌套徽标模型(具有文件附件)的组织 - 为简洁起见,已将其删除:
organisations/_form.html.erb
<%= form_for @organisation, html: {class: 'form-horizontal', role: 'form', multipart: true}, remote: true do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<p class='name error_explanation'></p>
<%= f.fields_for :operational_address do |fa| %>
<%= fa.label :postcode %>
<%= fa.text_field :postcode %>
<p class='operational_address postcode error_explanation'></p>
<% end %>
<%= f.fields_for :logo do |fl| %>
<%= fl.file_field :image %>
<p class='logo image error_explanation'></p>
<% end %>
<% end %>
organisations_controller.rb
def create
if @organisation.save
render :js => "window.location = '#{organisations_path}'"
else
render :validation_errors
end
end
组织/validation_errors.js.erb
$('.error_explanation').html('');
<% @organisation.errors.messages.each do |attribute, messages| %>
$('.<%= attribute %>.error_explanation').html("<%= messages.map{|message| "'#{message}'"}.join(', ') %>");
<% end %>