rails carrierwave - image url saved in db but file

2019-09-14 13:10发布

I have a form where I use cropit.js to crop an image. Button is onclick calling jquery function which takes result of cropit (cropped image) and with ajax push it to controller. Here it seems to work, but when I do this, everything looks ok, I dont see any error but the result is that url is stored in database with file name, but file itself is not stored in default uploads directory here is my model

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

here is my uploader

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

here is my controller

 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

this is the form

<%= 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 %>

and this is jquery part

$('#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" );
                     });

            };

any idea why file is not being saved in a folder? thanks

1条回答
姐就是有狂的资本
2楼-- · 2019-09-14 13:22

here is the solution I made finally...the issue was that I had to post file as a blob, not as base64 code. I've found function dataURItoBlob here on stackoverflow and implemented it

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" );
                     });
            };
查看更多
登录 后发表回答