Skip to content

Instantly share code, notes, and snippets.

@TheRealNeil
Created February 6, 2018 17:46
Show Gist options
  • Save TheRealNeil/2ba115b8b62f37b591dddbc8f278f3bb to your computer and use it in GitHub Desktop.
Save TheRealNeil/2ba115b8b62f37b591dddbc8f278f3bb to your computer and use it in GitHub Desktop.
Using the Trix Editor plus Private File Upload Attachments to S3
json.extract! photo, :id, :image_data, :created_at, :updated_at
json.url photo_url(photo, format: :html)
json.image_url image_url_photo_url(photo)
class PhotosController < ApplicationController
before_action :set_photo, only: [:show, :edit, :update, :destroy, :image_url]
...
def image_url
redirect_to @photo.image.url
end
...
end
Rails.application.routes.draw do
...
resources :photos do
get "image_url", on: :member
end
...
end
// Turn off the default Trix captions
Trix.config.attachments.preview.caption = {
name: false,
size: false
};
function uploadAttachment(attachment) {
var options = {
extension: attachment.file.name.match(/(\.\w+)?$/)[0], //Set the file extension
_: Date.now() //Prevent Caching
};
$.getJSON("/images/upload/cache/presign", options, function(result) {
// Create our form data to submit
var file = attachment.file;
var form = new FormData;
form.append("key", result['fields']['key']);
form.append("policy", result['fields']['policy']);
form.append("x-amz-credential", result['fields']['x-amz-credential']);
form.append("x-amz-algorithm", result['fields']['x-amz-algorithm']);
form.append("x-amz-date", result['fields']['x-amz-date']);
form.append("x-amz-signature", result['fields']['x-amz-signature']);
form.append("file", file);
// Create our XHR request
var xhr = new XMLHttpRequest;
xhr.open("POST", result['url'], true);
// Report file uploads back to Trix
xhr.upload.onprogress = function (event) {
var progress = event.loaded / event.total * 100;
attachment.setUploadProgress(progress);
}
// Tell Trix what url and href to use on successful upload
xhr.onload = function () {
if (xhr.status === 204) {
var image = {
id: result['fields']['key'].match(/cache\/(.+)/)[1],
storage: "cache",
metadata: {
size: attachment.filesize,
filename: attachment.filename,
mime_type: attachment.contentType
}
};
rails_form = new FormData;
rails_form.append("photo[image]", JSON.stringify(image));
$.ajax("/photos", {
contentType: false,
processData: false,
data: rails_form,
method: 'POST',
dataType: 'json'
}).done(function(data){
return attachment.setAttributes({
url: data.image_url,
href: data.url
})
});
}
}
return xhr.send(form);
});
}
// Listen for the Trix attachment event to trigger upload
document.addEventListener("trix-attachment-add", function(event) {
var attachment = event.attachment;
if (attachment.file) {
return uploadAttachment(attachment);
}
});
@gekong
Copy link

gekong commented Mar 23, 2021

Hello Neil, I'm also trying to build trix to work with S3 direct uploads. Will this work so that images are private? meaning it can't be seen by anyone else but the uploader? (I'm a rails newbie and a js newbie. I do need something that can be shared.)

@vitoyayo
Copy link

Hello Neil, thanks for share your code, can you tell me from where come that url? images/upload/cache/presign ?

@vitoyayo
Copy link

Hello Neil, I'm also trying to build trix to work with S3 direct uploads. Will this work so that images are private? meaning it can't be seen by anyone else but the uploader? (I'm a rails newbie and a js newbie. I do need something that can be shared.)

uploads to s3 works , but i have a little problem related with expire url from S3

@vitoyayo
Copy link

function uploadAttachment(attachment){
    let BASE_URL = window.location.origin;

    let file = attachment.file;
    let form = new FormData();
    form.append("Content-Type", file.type);
    form.append("photo[image_data]", file);
    let xhr  = new XMLHttpRequest;
    xhr.open("POST", "/photos.json", true);
    xhr.setRequestHeader("X-CSRF-Token", $.rails.csrfToken());
    xhr.upload.onprogress = function (event) {
        let progress = event.loaded / event.total * 100;
        attachment.setUploadProgress(progress);
    }
    xhr.onload = function(){
        if (xhr.status === 201) {
            console.log(xhr.status)
            let data = JSON.parse(xhr.responseText);
            return  attachment.setAttributes({
                url: `${BASE_URL}/photos/${data.id}/image_url`,
                href: `${BASE_URL}/photos/${data.id}/image_url`
            })

        }
    }
    return xhr.send(form);
}
document.addEventListener("trix-attachment-add", function(event) {
    let attachment = event.attachment;
    if (attachment.file) {
        return uploadAttachment(attachment);
    }

});

it's work for me

@gekong
Copy link

gekong commented Jul 5, 2021

function uploadAttachment(attachment){
    let BASE_URL = window.location.origin;

    let file = attachment.file;
    let form = new FormData();
    form.append("Content-Type", file.type);
    form.append("photo[image_data]", file);
    let xhr  = new XMLHttpRequest;
    xhr.open("POST", "/photos.json", true);
    xhr.setRequestHeader("X-CSRF-Token", $.rails.csrfToken());
    xhr.upload.onprogress = function (event) {
        let progress = event.loaded / event.total * 100;
        attachment.setUploadProgress(progress);
    }
    xhr.onload = function(){
        if (xhr.status === 201) {
            console.log(xhr.status)
            let data = JSON.parse(xhr.responseText);
            return  attachment.setAttributes({
                url: `${BASE_URL}/photos/${data.id}/image_url`,
                href: `${BASE_URL}/photos/${data.id}/image_url`
            })

        }
    }
    return xhr.send(form);
}
document.addEventListener("trix-attachment-add", function(event) {
    let attachment = event.attachment;
    if (attachment.file) {
        return uploadAttachment(attachment);
    }

});

it's work for me

this looks like your url is your local file not your aws file?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment