How to use File.new() in Rails app to create a file? - ruby-on-rails

I would like to create some_javascript_file.js after a user submits a form and save this file in the public directory of my app.
When testing this localy I can simply use File.new("./public/some_javascript_file.js", "w") to accomplish this but this solution doesn't work when the app is deployed to Heroku.
Please would you have any suggestions? Thank you

This is because of how Heroku works. Basically, as stated in the docs, the filesystem is ephemeral and you can't rely on it. If you want persistence, you should upload this JS file to some external service, such as AWS S3. Or you might want to deploy your app to a different environment, such as self-managed VPS, where filesystem is real and your file won't disappear.

Related

Best AWS Storage Option for Exporting Directories as .zip Files?

I'm brand new to AWS products, ruby on rails, web development, and coding of any type. For my first project after a quick (and dirty) bootcamp, I'm trying to build a ruby-on-rails website that stores images and allows the user to download them as a zip file. I used the RubyZip gem to accomplish this in my EC2 dev environment, but I have deployed to Elastic Beanstalk with S3 file storage, and the RubyZip gem seems unable to handle this structure without traditional directory targets for zipping.
My question is what's the best setup to achieve this functionality in EB? Disregarding the ruby constraint, zipping an S3 directory seems tricky. Should I move to EFS or another storage system? I plan to erase the folders regularly, and limit them to ~100 photos, so long term and large size storage are not a concern. Thanks very much!
Edit: I am attached to Ruby (only language I know), but not RubyZip, AWS, or much of anything else if they are not the best approach for this task.
I think you're on the right path as far as using S3 as a solution. The problem that your facing is that when you're interacting with S3 it's not like a folder on your local system, instead you're hitting the S3 API to interact with the files. (upload, edit, delete ect). This will be a problem you'll encounter with every AWS based storage solution.
I think the solution, in your case, is to fetch all of the photos and download them to a temporary folder on your local system. Then, you could zip them using Ruby, locally. After it's zipped, upload it back to S3.
Edit: By locally I mean onto the server where the Ruby application is running (not client-side)

Carrierwave + Heroku

Any idea how to use Carrierwave to upload images with Heroku.
I added this to the uploader file:
def cache_dir
"#{Rails.root}/tmp/uploads"
end
but images still don't save! After uploading an image, it saves and once you refresh the page, the image breaks.
Any help would be appreciated! Thanks
I do not think you can use Heroku and upload images without 3rd party storage service like Amazon S3.
https://devcenter.heroku.com/articles/s3
Heroku allows you store files inside tmp but just in order to send to a 3rd party service. Inside carrierwave uploader class you can set for example
storage :fog
instead of default :file and setup uploads to AWS S3. There are other options as well.
One thing is that if you are using a free tier instance on Heroku your upload needs to finish in abut a minute - I would recommend setup where you upload files directly to s3 account.
https://github.com/dwilkie/carrierwave_direct
Hope it helps
The filesystem on Heroku is not persisted. Only files uploaded through deployment mechanisms (git push) are "persisted". Others like the ones in your "#{Rails.root}/tmp/uploads" folder will be erased. That's why they are disappearing.
I have answered a similar question here. Here is a quote:
Your dyno on Heroku has a "read-only" filesystem. In a sense, your files will not be persisted between your dyno restarts and there is no guarantee that they will persist between any two requests. Here is an excerpt from the docs:
Each dyno has its own ephemeral file system, not shared with any other dyno, that is discarded as soon as you disconnect. This file system is populated with the slug archive so one-off dynos can make full use of anything deployed in the application.
You can use the #{Rails.root}/tmp folder as temporary folder, but you need to upload your files to some external storage (S3, some CDN, etc.). Heroku has some addons that makes it easy to handle.

heroku paperclip images appear but then disappear

I uploaded my app to heroku. The app was built with ruby on rails and had the activeadmin and paperclip gem installed. The files are configured properly and i was able to upload images using he active admin gem. this worked perfectly loaclly and worked fine on heroku until i uploaded more images, now all the images have disappeared. Any ideas on how this can be sorted?
Heroku has an ephemeral filesystem.
That is because each running dyno is an independent container (much like docker) which shared nothing with other dynos, and is destroyed when the app is restarted/deployed.
So any file written on disk will be lost when the dyno is restarted, and is not recoverable.
You need to configure paperclip to upload images to a dedicated file storage system like Amazon S3.
You can't store images on heroku, or anything for that matter. Your uploaded files are available for temporary use only, long enough to process them away to cloud storage elsewhere.
http://cloudinary.com/ offers development accounts for free; https://aws.amazon.com/s3/ has become ridiculously cheap and gives new devs a long free trial. There are other resources but ultimately you have to choose storage which isn't transient.
You can use gems like carrierwave, or attachinary to easily access and store with either of those storage locations.

Upload .mp3 file to public URL within Rails 4

I am using Rails 4.0.0 and Ruby 2.0.0, and I have an app deployed to Heroku.
I want to give my users the ability to upload a mp3 file. After it is completed uploading, I need them to get access to the public URL of that mp3 file. Right now, I could upload the recordings myself in my public directory, and then I could access them at a public URL.
I need to replicate that ability for my users. Any thoughts on the best way to do that?
Heroku generally doesn't want you to let people upload files onto the Heroku filesystem via your website. You need to use a third party file storage system. Most people use Amazon S3, and there are loads of detailed tutorials on how to use this with heroku (including on the heroku site). Google for "heroku amazon s3" and you'll see loads of helpful stuff, eg
https://devcenter.heroku.com/articles/s3

I want to use the fleximage gem and s3 for storage, but don't want dev/qa/test envs to use s3

I have a rails app that I'm going to host on engineyard and want to store image files on s3.
But I don't know if I want all developer machines to beusing s3 for storage of all our test and dev images. Maybe it's not an issue -- but it seems like a waste to have everyone storing all our images in s3.
I've heard of some ppl who store images on s3 'hacking' dev environments to store images locally on the file system -- and then using s3 in prod only.
What are other people doing?
You could write a wrapper class around the gem that uses the file system for image storage instead of S3 for non-production environments. Then your application would use the wrapper rather than the gem directly. Or make the image store the wrapper uses a configuration option.
I use why's old Camping app, parkplace. It behaves like (most?) of the S3 API, but runs locally. The new location for it is here: http://github.com/technoweenie/parkplace

Resources