railscarrierwave - 图像网址保存在数据库中但文件未保存

Posted

技术标签:

【中文标题】railscarrierwave - 图像网址保存在数据库中但文件未保存【英文标题】:rails carrierwave - image url saved in db but file not saved 【发布时间】:2016-03-02 17:44:39 【问题描述】:

我有一个表单,我使用cropit.js 裁剪图像。按钮是 onclick 调用 jquery 函数,该函数获取cropit(裁剪图像)的结果并使用 ajax 将其推送到控制器。在这里它似乎可以工作,但是当我这样做时,一切看起来都很好,我没有看到任何错误,但结果是 url 以文件名存储在数据库中,但文件本身未存储在默认上传目录中 这是我的模型

 class Project < ActiveRecord::Base
  mount_uploader :profile_pic, ProjectProfileUploader 
end

这是我的上传器

class ProjectProfileUploader < CarrierWave::Uploader::Base
   include CarrierWave::RMagick

  storage :file

  def store_dir
    "uploads/#model.class.to_s.underscore/#mounted_as/#model.id"
  end

  version :resized do
    process :resize_to_fill => [800,506]
  end

end

这是我的控制器

 def saveprofilepic

    @p=Project.find(params[:id])
    @p.profile_pic = (params[:data])
    respond_to do |format|
    if @p.save

        format.html  redirect_to @p, notice: 'Project was successfully updated.' 
        format.json  render :show, status: :created, location: @p 
      else
        format.html  render :new 
        format.json  render json: @p.errors, status: :unprocessable_entity 
      end
    end
  end

这是表格

<%= form_for @project do |f| %>

                          <div class="cropit-preview" id="cropit-preview"></div>

                          <div class="rotation-btns"><span class="icon icon-rotate-left rotate-ccw-btn"><i class="fa fa-arrow-left"></i>

                        </span><span class="icon icon-rotate-right rotate-cw-btn"><i class="fa fa-arrow-right"></i>

                        </span></div>

                          <input type="range" class="cropit-image-zoom-input " />

                          <%= f.file_field :profile_pic, accept: "image/jpeg, image/jpg, image/gif, image/png", :class=> "cropit-image-input" %> 

                         <%= button_tag "Pridaj obrázok", :class=>'btn-u', :onclick=>"getimage()",:type => 'button' %>

                          <% end %>

这是 jquery 部分

$('#image-cropper').cropit(
        imageState: src: <% if @project.profile_pic.nil? %>"<%= asset_path( 'img_empty_800.jpg' ) %>" <% else %> "<%= @project.profile_pic.url(:resized).to_s %>" <% end %> );
           $('.select-image-btn').click(function() 
          $('.cropit-image-input').click();
        );
        // Handle rotation
        $('.rotate-cw-btn').click(function() 
          $('#image-cropper').cropit('rotateCW');
        );
        $('.rotate-ccw-btn').click(function() 
          $('#image-cropper').cropit('rotateCCW');
        );

        function getimage()
        var $cropedimage = $('#image-cropper').cropit('export', 
              type: 'image/jpeg',
              quality: .9,
              originalSize: true
            );
         $.ajax(
                    type: "POST",
                    url: "/saveprofilepic",
                    data: 
                        id: <%= @project.id %>,
                        data: $cropedimage
                        )
                    .done(function (msg) 
                    alert("Obrázok bol nahratý na server" );
                     );

            ;

知道为什么文件没有保存在文件夹中吗? 谢谢

【问题讨论】:

当我阅读有关 ajax 的内容时,它看起来与 formData 对象有关……但是当我使用 formData 并将它们传递给控制器​​时,图像仍然没有保存任何关于如何使用 formData 和处理数据的想法在控制器中? 【参考方案1】:

这是我最终提出的解决方案...问题是我必须将文件作为 blob 发布,而不是 base64 代码。我在***上找到了函数dataURItoBlob并实现了它

function getimage()
        var $cropedimage = $('#image-cropper').cropit('export', 
              type: 'image/jpeg',
              quality: .9,
              originalSize: true
            );


        function dataURItoBlob(dataURI) 
    // convert base64/URLEncoded data component to raw binary data held in a string
    var byteString;
    if (dataURI.split(',')[0].indexOf('base64') >= 0)
        byteString = atob(dataURI.split(',')[1]);
    else
        byteString = unescape(dataURI.split(',')[1]);

    // separate out the mime component
    var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];

    // write the bytes of the string to a typed array
    var ia = new Uint8Array(byteString.length);
    for (var i = 0; i < byteString.length; i++) 
        ia[i] = byteString.charCodeAt(i);
    

    return new Blob([ia], type:mimeString);


    var filedata=dataURItoBlob($cropedimage);


        var fd = new FormData();
        fd.append('data', filedata, "project-" + <%= @project.id %> + "-profile-pic.jpg" );
        fd.append('id', <%= @project.id %>);
           $.ajax(
                    type: "POST",
                    url: "/saveprofilepic",
                    data: fd,
                    processData: false,
                    contentType: false,
                    cache: false                   
                        )
                    .done(function (msg) 
                    alert("Obrázok bol nahratý na server" );
                     );
            ;

【讨论】:

以上是关于railscarrierwave - 图像网址保存在数据库中但文件未保存的主要内容,如果未能解决你的问题,请参考以下文章

带有 JQuery Uploader 的 Rails Carrier Wave

如何以编程方式保存来自 URL 的图像?

使用 js 从网站下载或仅保存图像文件

将图像保存在 iOS 相册(我的文件夹)中并存储图像 url

需要工作表脚本将图像保存到驱动器

使用 Python 请求从 URL 保存图像 - URL 类型错误