Ask A Question


You’re not receiving notifications from this thread.

Multiple File Uploads with Shrine Discussion

Scott Tallarida Scott Tallarida

This is fantastic! Exactly what I needed so THANK you! I am having one very strange issue that I wonder if anyone has experience with. "Larger" files uploaded - meaning over a mg end up getting rendered sideways in the browser when referencing uploaded S3 url...small files (in my example 28kb) render correctly. This is driving me pretty crazy


I'm not sure if this matters (I know it does with video) but do your photos happen to have been taken at the other orientation originally? I'm not sure if the browser may be reading some metadata and rotating them automatically or not.

Scott Tallarida Scott Tallarida

ok, so I am experiencing an interesting behavior that I think is important for this approach to scale...any help would be appreciated!

I am using this process to upload high numbers of images so I only think this is relevant when uploading more than 10 or so...I will be uploading hundreds at a time.

I have the following logic in image_uploader.rb to correctly orient the image and resize:

process(:store) do |io, context|
file =
resize_to_limit!(file, nil, 640)

This functions correctly. HOWEVER, rails is still working on these files well after the last progress bar has reached 100%. If the user refreshes the page during this time, the "remaining" images will get uploaded without processing - meaning sideways and huge. They still go to amazon but they skip the process method.

So my question is two-fold. Anyone have an idea how to:

1) wrap the progress bar around the "entire" process?
2) either NOT upload the unprocessed files, identify them or, of course, fix the problem entirely!!

Any help or thoughts would be appreciated.


I think best behaviour is to send data of each file to the Rails app as soon as it's uploaded to S3.

That gives great user experience, because even if they terminate the upload at some point, the files that were uploaded before stay uploaded. That's why e.g. Flickr upload interface really sucks, because it's all-or-nothing - if there is an error or you have to terminate the multiple file upload midway, nothing stays uploaded.

It is also the most performant, because the server can already start processing each file as soon as it's uploaded to S3, instead of holding off and then sending all files at once.

The shrine-rails-example app already demonstrates this flow, so you can draw your inspiration from there.


How should I change the update.js on using the versions plugin? And I can't see the progress bar in Bootstrap 4 and so any solution?


JavaScript looks exactly the same if you're using the versions plugin, because direct upload is just another way of caching the file (you're uploading it to temporary storage directly via the client rather than have the server upload it), and processing versions happens on promoting (when cached file is moved to permanent storage).


Thanks a whole bunch for doing this series. Invaluable! Exactly what I needed.


I want to crop uploaded image or cached image before uploading. I tried it on "after_update" callback but it is difficult to reupload the UploadedFile after cropping. Wound you give me a hint for this?


You can use the recache plugin, which adds another processing step between caching and promoting, triggered before the record is saved. So you can just download the cached file there, crop it, and upload it to cache storage again.


I'm trying to store files in different folders in the same S3 bucket. Let's say I have two models, document and image. How can I store the corresponding files in two folders instead of "store". I was reading the following, but can't find how to get this done: Any ideas where I can find this information? Thanks!


You can choose how you generate the location in your uploader:

class ImageUploader < Shrine
def generate_location(io, context)

class DocumentUploader < Shrine
def generate_location(io, context)

Feel free to post any general Shrine questions on the Shrine Google group ;)


One small issue I'm running into.. since photos are displayed after uploading with js it's necessary to refresh the page for rails handling to kick in. For example, new images are not linked to their own show pages until a refresh. Also, the max width setting is removed after a refresh, since rails takes over.

Is there any way to handle all display options with rails from the start, so that no page refresh is necessary?


Hey Chris, nice work your tutorials on direct upload with Shrine. I've been following
along sticking pretty much to the original code. But now I got stuck when I was
trying to make this work with different image versions.

This is my albums/show.html.haml:

%p#notice= notice
- do |photo|
%a{:href => photo.image_url(:size_1000)}
%img{alt: photo.caption , src: photo.image_url(:thumb)}
-if user_signed_in?
= render partial: "photos/form", locals: {photo:}
= link_to 'Edit', edit_album_path(@album)

Since I have to specify now the image version, the original _photo.json.jbuilder
partial won't work anymore. So I modified it like this:

json.extract! photo, :id, :created_at, :updated_at
json.image_url(:size_1000) photo.image[:size_1000].url
json.image_url(:thumb) photo.image[:thumb].url
json.url album_photo_url(@album, photo, format: :json)

But this gives me a syntax error:

SyntaxError (path_to_rails_app/app/views/photos/_photo.json.jbuilder:2: syntax error, unexpected tIDENTIFIER, expecting keyword_end

Any advice for me?


Can someone help me understand what this error means?

My jquery uploaded progress bar isn't moving and I'm running this into error: ActionController::RoutingError (No route matches [GET] "/images/upload/cache/presign"):


Sounds like you're missing the routes for Shrine. Make sure this is in your routes file.

Has anyone had any luck getting this working rendering image templates/partial instead of just an image (mentioned as an alternative at around 11.30 in the video)? 

Chris has been kind enough to try and help out but my code differs. I'm unsure where to put the "json.template" section, tried in the show.json.jbuilder and the _attachment.json.jbuilder and how to alter it to suit my attachment model. Got errors and sometimes continuous loops. 

I'd be super grateful for any help or advice:

Here's some of my code:
Join the discussion
Create an account Log in

Want to stay up-to-date with Ruby on Rails?

Join 83,770+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.