Rails [求助] Rails 5 上传文件后,验证的错误信息怎么在 ajax 中显示?

Sylor-huang · 2018年09月28日 · 最后由 Sylor-huang 回复于 2018年09月28日 · 1147 次阅读

我用的是 Rails 5 和 carrierwave 上传文件。如果文件上传成功的话,Ajax 可以显示相关信息;但是文件上传失败的话,返回的错误信息不能再 Ajax 中显示。

以下为相关代码:

## documents_controller.rb

def create
    # 浮动窗口上传
    @document = Document.new(document_params)
    @document.file_name = params[:file]
    @document.user_id = current_user.id
    respond_to do |format|
      if @document.save
        format.json {render json: { id:@document.id }}
      else
        format.json { render :json => { :error => @document.errors }, status: :unprocessable_entity}
      end
    end
  end


## document.rb

class Document < ApplicationRecord
  belongs_to :user, optional: true
  before_validation :set_documents_attributes
  validate :file_extension
  validates_uniqueness_of :md5hash, :on => :create,message: "文件已存在!"
  validates_presence_of :file_name,message: "上传文件名不能为空!"
  validate :check_file_size
  mount_uploader :file_name, ImageUploader

  private
  def file_extension
    file_extension = file_name.file.extension.downcase
    errors.add(:file_name, "文件类型错误,仅支持文档类型!") unless %w(rtf pdf doc docx xls xlsx html txt epub mobi rar zip 7z ppt wps gz pptx chm htm).include?(file_extension)
  end

  def check_file_size
    errors.add(:file_size, "文件不能大于200M.") if self.file_size > 200.megabytes
  end

  def set_documents_attributes
    if file_name.present? && file_name_changed?
      self.file_type = file_name.file.content_type
      self.file_size = file_name.file.size
      self.md5hash = Digest::MD5.hexdigest(self.file_name.read)
    end
  end
end

点击上传的按钮

<%= file_field_tag :document, id: "uploadFiles" %>

上传的 Js 内容

let localFileUpload = $("#uploadFiles");
    localFileUpload.on("change",function () {
        let formData = new FormData();
        formData.append("file",localFileUpload[0].files[0]);
        let document_name = localFileUpload[0].files[0].name;
        let document_status = $("div.uploadStatus");
        let document_attr = document_name.split('.').pop();
        let document_ext = document_name.substr(0, document_name.lastIndexOf('.'));
        let type_array = ['pdf','rtf', 'doc', 'docx', 'xls', 'xlsx', 'html', 'txt', 'epub', 'mobi', 'rar', 'zip', '7z', 'ppt', 'wps', 'gz', 'pptx', 'chm', 'htm'];
        if($.inArray(document_attr,type_array) === -1){
            document_status.removeClass('hide').html("<span class='text-red'>文件格式错误,仅支持文档格式!</span>");
        }else{
            $.ajax({
                url : '/documents',
                type: "POST",
                data: formData,
                dataType: "JSON",
                processData: false,
                contentType: false,
                xhr:function(){
                    let myXhr = $.ajaxSettings.xhr();
                    if(myXhr.upload){
                        myXhr.upload.addEventListener('progress',function(e){
                            let loaded = e.loaded;                  //已经上传大小情况
                            let total = e.total;                      //附件总大小
                            let percent = Math.floor(100*loaded/total)+"%";     //已经上传的百分比
                            let fileSize = (total / Math.pow(1000, 2)).toFixed(1) + ' M';
                            localFileUpload.parent("div.localUploadForm").css({"opacity":"0.5","cursor":"not-allowed"});
                            localFileUpload.attr("disabled",true);
                            document_status.removeClass("hide");
                            $(".uploadFileType").html(document_attr);
                            $(".uploadFileSize").html(fileSize);
                            $(".processPercent").html(percent);
                            $(".processBar").css("width",percent);
                            $("input[data-type='attachment_type']").val(document_attr);
                            $("input[data-size='attachment_size").val(fileSize);
                            $("input[data-alt='attachment_title']").attr("disabled",true);
                        }, false);
                    }
                    return myXhr;
                },
                success: function (res) {
                    $("input[data-alt='attachment_title']").attr("disabled",false).val(document_ext);
                    let delete_html = "<a data-method='delete' href='/documents/" + res.id +
                        "' data-confirm='确认删除上传的文件吗?'><i class='fa fa-trash mr2 fa-fw'></i>删除</a>";
                    $("span.uploadFileDelete").html(delete_html);
                    $(".uploadFileSuccess").html("上传成功");
                    $("input[data-attachment='attachment_url").val(res.id);
                },
                error: function (res) {
                    for(let message of res.error){
                         console.log(res.error[message]);
                     }
                }
            });
        }
    });

当文件上传失败时,Ajax 中 error 不能获得documents_controller.rb中返回的 json 错误信息,上传成功时,可以获得 json 的信息。 请问我该怎么修改?非常感谢!

format.json { render :json => { :error => @document.errors,status: :unprocessable_entity }}

改成

format.json { render :json => { :error => @document.errors }, status: :unprocessable_entity }

@ThxFly 谢谢你的提醒,已更正了,但是现在又提示错误: Uncaught TypeError: res.error is not iterable,请问该怎么做呢?非常感谢。

@ThxFly 我在浏览器里已经可以获得了错误信息,但是怎么用 ajax 来显示呢?谢谢

Sylor-huang 关闭了讨论。 09月28日 20:38
需要 登录 后方可回复, 如果你还没有账号请 注册新账号