All threads / Upload Progress with Refile Javascript Discussion
Ask A Question


You’re not receiving notifications from this thread.

Upload Progress with Refile Javascript Discussion

Hello Chris, is there a good gem to build a progress bar? (for example, show % complete based on how many episodes you've watched)

As long as you can calculate the percentage, all you need is some CSS. Bootstrap ships with a progress bar and all you need to do is set the width to the percentage complete.

You can find many others if you're not using Bootstrap and you just google "css progress bar"

Anthony Candaele ·

Hi Chris,

I tried to implement the immediate showing of the image from the cache, but it's not working. When I check the rendered code in my browser, I don't see the member_cache_id for the hidden field (in your example it's film_cache_id. The hidden field looks like this:

<input value="{}" type="hidden" name="member[image]">

I double checked the form field, it's exactly the same as the upload field in your example:

<%= f.attachment_field :image, direct: true %>

I also set the :image_cache_id in the allowed params of the member controller

So I'm not sure why the member_image_id is not set in the hidden field.

my code is at:



Hey Chris, do you know of a way to directly post to refile from a mobile app?

If you pass the same parameters to the URL as the HTML form that gets generated it will work. Of course, you will need to make sure the mobile user has a way to authenticate as a user for that request by setting a cookie or using an API token. Mobile apps talking to a Rails app are basically the same as your browser, you just have to worry about things like cookies/API tokens.

For anyone using the latest version of refile (0.5.3), you will need to access cache_id differently because this is what gets returned.

<input value="{" id":"8c27104d22efe3de9b463bc8757e39ed2b632337e06628c2d8adf22c7b45","filename":"img_0741.jpg","content_type":"image="" jpeg","size":1064417}"="" type="hidden" name="user[image]">

image_info = $("input[name='user[image]']").val()
image_id = JSON.parse(image_info).id

Looks like I'll need to amend this episode. Thanks for the heads up!

Anthony Candaele ·

Hi Chris, yeah, I would be interesting to see a video on how to store uploads on Amazon S3, and other Refile configurations.

I came up with the same code as above after I saw that the video doesn't match the current version of refile (0.5.3). However I found that it did't work, and the value of the hidden input was always null when I would try to get the id. It worked just fine in the console, but never from the page itself. So I wrapped the above code in:

setTimeout(function() { }, 0);

and it works fine.

Never mind. I was binding to upload:complete instead of upload:success. I copied the code from the refile Github page, and it has the same code you have in the video, except it has upload:complete instead of upload:success like in your video. Makes sense why it wasn't working without the setTimeout now.

Anthony Candaele ·

Hi Chris, is there a way to make the script more generic, so that it's not only fetching film_image_id images but also for instance new_article_image_id images ?



Anthony Candaele ·

found a solution with:

image_value = JSON.parse $("[id$=_image_cache_id]").val()

Anthony Candaele ·

found a solution to print the filename of an uploaded file on this page:

just generate a migration to add a filename field to the table, for example:

add_column :news_articles, :document_filename, :string

now you can read out filenames like this:

<%= link_to @news_article.document_filename, attachment_url(@news_article, :document) %>

icsvortex666 ·

Hi Chris :D, can you upload a tutorial on how to store the images on AWS using Refile (n00b here)
Thanks :)

I can but it might take a while. In the meantime, you can check out their backend section. It pretty much walks you through it all. Just need to know your Key and bucket name from AWS. Just create your S3 bucket first and fill in the rest.

Marc Knapp ·

Hello Chris,

I added your coffee script for displaying upload progess, but it returns an NaN error

$(document).on "upload:progress", "form", (e) ->
detail = e.originalEvent.detail
percentComplete = Math.round(detail.loaded / * 100)
$("#image").text("#{percentComplete}% uploaded")

Any ideas?


Todd Quillen ·

Change the percent complete line to:

percentComplete = Math.round(detail.progress.loaded / * 100)

Notice how "progress" was added after the detail in between the loaded and total.

You have solved this problem?

Seems like the solution to show a preview image will not work any longer the latest version of refile. Even with Olivier 's suggestion to get the image id using the below code will not work as you will get a 403 (forbidden error).

image_info = $("input[name='user[image]']").val()
image_id = JSON.parse(image_info).id

Urls for version 0.6+ are signed with a token. Hence the new url will be:

imageUrl = '/attachments/' + token + '/cache/fill/360/360/' + imageId + '/image'

Will update this post if I find a way to do this. Or if anyone else has a solution, please do share.

Yeah, with the new token system, this might be a piece of data you can get somewhere. I'd ask on the Refile Github issues and see what you find out. If you find a solution, let me know!

@excid3:disqus yea it seems that's it's not currently possible to do so.

@Ariff , I saw your issue posted on refile's github page where @jnicklas suggested to do a roundtrip to the server. Have you found a good solution for that?

Hey @szilardmagyar:disqus I did not implement a solution. For one of my apps I was still using the older version of refile and only admin are allowed to upload images. So there was no issue about the security bug.

As for my other app, I just did not implement the preview feature as I felt that it was not critical at this current moment. Will revisit the issue when I have the time. Nonetheless, I think a simple solution is to write your own javascript to show the image directly from your file system and not use Refile. So just add an image tag with the source as the file path of the image and load/show it using javascript. Doing a round trip to the servers will defeat the purpose as it will still only work after the image has been uploaded.

Hope this helps.

@Ariff, thanks for the quick answer! Do you have any code sample for that? I'm not that good at coding yet and not sure if I find the optimal solution. Thanks in advance!

Chris, if I upload a file with <%= form.attachment_field :message_attachment, direct: true, presigned: true, class: "choosefile" %> it gets uploaded to my s3 bucket (so everything seems to be working fine), yet when I display the filenames with url pathlike <%= link_to "#{message.message_attachment_filename}", attachment_url(message, :message_attachment),:target => "_blank" %>, it's served from my app (href=/attachments/....) instead of S3. Can you guess where things go wrong? Based on refile description files shouldn't hit my app at all with these settings.

That's actually how it's supposed to work actually because it provides you the ability to generate different image sizes on the fly. The downside to this is it requires you to setup a CDN so that it doesn't have to generate the image every single request. You can check out the readme for some more information on that.

I will checkout with the CDN, but how can the files be served from myapp/attachments if the files never even touch the app (according to refile docs)?

That's because the sinatra app (which Refile is referring to) gets mounted to your Rails app at /attachments. Rails basically routes the URL over to the Sinatra app, effectively so that the files never hit your Rails code. It just gets diverted before Rails would start processing it. And then files are served up from the same url because that's where the Sinatra app is.

So basically files are stored on S3, and when I try to use them in my app they will be fetched from S3 and get mounted by the sinatra app (to generate different size if pic), so an end user only will see the url as app/attachments? If so, is this the preferred way even if I don't want to display the picture? When I said display in my original question I meant displaying only the filename and the link to the url. My goal is to provide a way for users to send over each other jpeg/pdf/doc/etc. files. If they are interested in checking out a pic/doc/pdf then they can click on the file names which are listed in the app and the files get downloaded (doc/xls) or opened in a new tab with S3 (pdf/jpeg).

You can setup Refile to cache some file metadata like the filename to your model.

That should take care of showing the filename and then anytime the URL is clicked, then that's when Refile will download the file. Just displaying the link won't cause it to download the file just to render the filename in the link.

Join the discussion

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

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

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

    logo Created with Sketch.

    Screencast tutorials to help you learn Ruby on Rails, Javascript, Hotwire, Turbo, Stimulus.js, PostgreSQL, MySQL, Ubuntu, and more. Icons by Icons8

    © 2023 GoRails, LLC. All rights reserved.