jquery fileupload rails s3 shrine image upload error

Uncle Hank

I am sort of new to rails and I am trying to upload images directly to S3 with Shrine. I got direct uploads to S3 to work perfectly, however, when I introduced jquery file upload and upload an image, chrome console throws this error at me. I'm not sure what I'm doing wrong and I can't seem to find a solution anywhere online. I get that it's a presign error and it's probably not finding the cache link but I don't know how to resolve that.

EDIT: This was solved by including the presign code in the Routes file and altering the storage location in the uploads.js to the correct location. Now, however, I have an issue with the files being rolled back when they attempt to upload.

I'm using the cloud based ide C9,

This is my uploads.js file:

$(document).on("turbolinks:load", function(){
$("[type=file]").fileupload({
  add: function(e, data) {
      console.log("add", data);
      data.progressBar = $('<div class="progress"><div class="determinate" 
style="width: 70%"></div></div>').insertBefore("form")
      var options = {
          extension: data.files[0].name.match(/(\.\w+)?$/)[0], //set the 
file extention
         _: Date.now() //prevent caching
      };

      $.getJSON("/autos/upload/cache/presign", options, function(result) {
          console.log("presign", result);
          data.formData = result['fields'];
          data.url = result['url'];
          data.paramName = "file";
          data.submit()
      });

  },
  progress: function(e, data) {
  console.log("progress", data);
  var progress = parseInt(data.loaded / data.total * 100, 10);
  var percentage = progress.toString() + '%'
  data.progressBar.find(".progress-bar").css("width", 
percentage).html(percentage);
  },
  done: function(e, data) {
  console.log("done", data);
  data.progressBar.remove();


  var image = {
    id:       data.formData.key.match(/cache\/(.+)/)[1], // we have to 
remove the prefix part
    storage:  'cache',
    metadata: {
      size:      data.files[0].size,
      filename:  data.files[0].name.match(/[^\/\\]+$/)[0], // IE return full 
path
      mime_type: data.files[0].type
    }
  }
  form = $(this).closest("form");
  form_data = new FormData(form[0]);
  form_data.append($(this).attr("name"), JSON.stringify(image))

  $.ajax(form.attr("action"), {
    contentType: false,
    processData: false,
    data: form_data,
    method: form.attr("method"),
    dataType: "json"
    }).done(function(data) {
        console.log("done from rails", data);
        });
  }
  }); 
});

My routes.rb file includes:

mount ImageUploader::UploadEndpoint => "/images/upload"

mount Shrine.presign_endpoint(:cache) => "/autos/upload/cache/presign"

I have a model which accepts these images as well as other fields called Autos, this is included in the Autos file:

include ImageUploader[:image]

My Autos Controller is:

class AutosController < ApplicationController
  before_action :find_auto, only: [:show, :edit, :update, :destroy]
  def index
    @autos = Auto.all.order("created_at DESC")
  end

  def show
  end

  def new
    @auto = current_user.autos.build
  end

  def create
    @auto = current_user.autos.build(auto_params[:auto])

    if @auto.save
      flash[:notice] = "Successfully created post."
      redirect_to autos_path
    else
      render 'new'
    end
  end

  def edit
  end

  def update
    if @auto.update(auto_params[:auto])
      flash[:notice] = "Successfully updated post."
      redirect_to auto_path(@auto)
    else
      render 'edit'
    end
  end

  def destroy
    @auto.destroy
    redirect_to autos_path
  end

  private 

  def auto_params
    params.require(:auto).permit(:title, :price, :description, :contact, :image, :remove_image)
  end

  def find_auto
    @auto = Auto.find(params[:id])     
  end
end
Wasif Hossain

Assuming your image_uploader.rb has the ImageUploader class defined and given that your presign endpoint is something like /autos/upload/cache/presign, your routes.rb should have the presign route defined like so:

mount ImageUploader.presign_endpoint(:cache) => '/autos/upload/cache/presign'

I hope this single change in the route file would make you able to get the presign object that should contain 3 keys: url, fields and headers

# GET /autos/upload/cache/presign
{
  "url": "https://my-bucket.s3-eu-west-1.amazonaws.com",
  "fields": {
    "key": "cache/b7d575850ba61b44c8a9ff889dfdb14d88cdc25f8dd121004c8",
    "policy": "eyJleHBpcmF0aW9uIjoiMjAxNS0QwMToxMToyOVoiLCJjb25kaXRpb25zIjpbeyJidWNrZXQiOiJzaHJpbmUtdGVzdGluZyJ9LHsia2V5IjoiYjdkNTc1ODUwYmE2MWI0NGU3Y2M4YTliZmY4OGU5ZGZkYjE2NTQ0ZDk4OGNkYzI1ZjhkZDEyMTAwNGM4In0seyJ4LWFtei1jcmVkZW50aWFsIjoiQUtJQUlKRjU1VE1aWlk0NVVUNlEvMjAxNTEwMjQvZXUtd2VzdC0xL3MzL2F3czRfcmVxdWVzdCJ9LHsieC1hbXotYWxnb3JpdGhtIjoiQVdTNC1ITUFDLVNIQTI1NiJ9LHsieC1hbXotZGF0ZSI6IjIwMTUxMDI0VDAwMTEyOVoifV19",
    "x-amz-credential": "AKIAIJF55TMZYT6Q/20151024/eu-west-1/s3/aws4_request",
    "x-amz-algorithm": "AWS4-HMAC-SHA256",
    "x-amz-date": "20151024T001129Z",
    "x-amz-signature": "c1eb634f83f96b69bd675f535b3ff15ae184b102fcba51e4db5f4959b4ae26f4"
  },
  "headers": {}
}

When upload starts, you will now find this object in developer console instead of the previous 404 not found error.


UPDATE

I think you are very close to the solution. In your create/update actions, use auto_params[:auto] instead of auto_params

You would also like to check the RoR guide on Association Basics for collection methods

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Upload to Rails Shrine from NativeScript

FileUpload to upload image fail to save the image, but no error message displayed

Rails 5 + Shrine multiple files upload

Render a Markdown file stored in S3 uploaded with shrine - Rails

RoR, Paperclip and S3 upload image error

Upload Image with FileUpload and Stock in database

Shrine with Rails multiple polymorphic image uploads

Setting the Content-Type in direct to S3 upload using Rails and jQuery File Upload

Upload file to s3 on client side with rails, carrierwave-direct, and jquery file upload

Upload images to different folders in s3 (by album names) using Shrine gem

jQuery File Upload in Rails 4 with Image Resizing

How to upload while resizing the original image itself in Shrine

S3 image upload error with boto3 and dropzone.js

How to upload image using express-fileupload?

Upload image to AWS s3 storage from Laravel showed Heroku Server 500 Error

AWS S3 Bucket Django 3.0 User Profile Image Upload Access ERROR

AWS S3 Bucket Django 3.0 User Profile Image Upload Access ERROR

AWS S3 Bucket Django 3.0 User Profile Image Upload Access ERROR

Upload images from clipboard using jquery fileupload

jQuery-File-Upload - TypeError: $(...).fileupload is not a function

Error trying to upload an image with js, jquery and PHP

Codeigniter Image upload using jquery and ajax error

upload image dataset to S3 sagemaker

PHP resize an image and upload to s3

Upload image in local folder to S3

Image upload to s3 does not render

AngularJs Image upload to S3

Amazon S3 - Carrierwave Image Upload

Laravel Upload Image to Amazon s3