I'm working on a web application right now using Rails and wanted to see if anyone knew of a good way to keep track of file storage limits? We want to give users a specific amount of room that they can use to upload files and we are using paperclip for storage on Amazon S3. Any thoughts? Thanks
One of the optional columns you can use with paperclip is the OBJECT_file_size which you can sum up like
# Assuming a user has many files relationship
#user.uploads.sum(:image_file_size)
As to the actually imposing the cap, I'd recommend creating a custom validation on whatever the file model is so that you can pass errors and issues back to the client.
Paperclip stores the file size.
So you could just, for one user, do something like :
def used_file_size
self.files.sum(:document_file_size)
end
You'll then have the total size of every user's documents.
You can then add a max size limit and not validate the document's upload if the user has reached that size.
Related
I'm making a demo for a ruby gem I created that process images and I have my application for the demo using the gem. I want the demo to allow the user to upload an image and try the demo but I don't really want to store the image in a database.
I read about redis but I'm not sure if is the right solution since I don't think is intended to be used with images.
maybe you could simply ask the user to upload an image address as a string rather than a file?
Storing in Redis is not a bad idea, you could also set an expiry date to delete keys older than x days / hours. But keep in mind that Redis is still a database which you need to maintain.
Another approach is to just store it on the filesystem and delete the oldest file before storing a new one so you only store the latest x files.
http://qnimate.com/storing-binary-data-in-redis/
maybe you could simply ask the user to upload an image address as a string rather than a file?
I like this approach by Hassan, you could ask the user to upload to Dropbox / Google files for instance. Or ask to enter the email address and use Gravatar. This would be a light weight approach so if it's just an example I would go for this.
This is my first Rails project. I'm a bit stumped on how image files should be saved in the database, since they take up a lot of space. My site is going to be one where people upload a lot of images. In my migration for creating the pictures table, would I save the image file name as a string? Also does anyone have hints on where to save the images (assets, public, etc)?
Sorry, I'm just a noob looking for a little guidance.
You should consider storing your images on Amazon's S3 (or a similar alternative) instead of the database. You can use gems like paperclip to help you with uploading to a remote storage server.
However, if you really do want to store the binary image data in the database, then you probably want to use 'blob' as the column datatype.
You can also use carrierwave. Just create a string column and mount an uploader on it.
Blobs should only be used in special cases!
You save the images as files on a storage system on a server or the cloud. Then, you create a record in your table with the path to it.
Do not store an images byte for byte\BOLB.
I am using Paperclip to, among other things, allow a registered user to upload an avatar for use on thier profile. I want to store a big and small version of the image which will be rmagicked to standard sizes. Now, what i want to do, is store these two standard sizes (:normal and :tiny, for example.) but I do not want to store the :original.
This will be nice for several reasons as I will never display or use any version than the two standard (re)sizes.
What is your reasoning for wanting to delete the files? File storage is so cheap now, that it's not really a valid reason anymore.
I would advise against deleting the original files. If you ever decide you want to resize the files using Paperclip's rake tasks, you will need the originals.
I can't think of an way to do that with Paperclip directly, but you could remove the original manually after creating the record. An example could look like this:
class Photo
has_attached_file :photo
after_create :destroy_original
protected
def destroy_original
# photo.url will look something like /system/photos/1/original.png
File.unlink("#{Rails.root}/public#{self.photo.url}")
end
end
Im desiging an app which allows users to upload images (max 500k per image, roughly 20 images) from their hard drive to the site so as to be able to make some custom boardgames (e.g. snakes and ladders) in pdf formate. These will be created with prawn instantly and then made available for instant download.
Neither the images uploaded nor the pdfs created need to be saved on my apps side permanently. The moment the user downloads the pdf they are no longer needed.
Heroku doesn't support saving files to the system (it does allow to the tmp directory but says you shouldnt rely on it striking it out for me). I'm wondering what tools / services I should be looking into to get round this. Ive looked into paperclip, I'm wondering if this is right for this type of job.
Paperclip is on the right track, but the key insight is you need to use the S3 storage backend (Paperclip uses the FS by default which as you've noticed is no good on Heroku). It's pretty handy; instead of flushing writes out to the file system, it uses the AWS::S3 gem to upload them to S3. You can read more about it in the rdoc here: http://github.com/thoughtbot/paperclip/blob/master/lib/paperclip/storage/s3.rb
Here's how the flow would work:
I'd let your users upload their multiple source images. Here's an article on allowing multiple attachments to one model with paperclip: http://www.cordinc.com/blog/2009/04/multiple-attachments-with-vali.html.
Then when you're ready to generate the PDF (probably in a background job, right?), what you do is download all the source images to somewhere in tmp/ (make sure the directory is based on your model id or something so if two people do this at once, the files don't get stepped on). Once you've got all the images downloaded, you can generate your PDF. I know this is using the file system, but as long as you do all your filesystem interactions in one request or job cycle, it will work, your files will still be there. I use this method in a couple production web apps. You can't count on tmp/ being there between requests, but within one it's reliably there.
Storing your generated PDF on S3 with paperclip makes sense too, since then you can just hand your users the S3 URL. If you want you can make something to clear the files off every so often if you don't want to pay the S3 costs, but they should be trivial.
Paperclip sounds like an ideal candidate. It will save images in RAILS_ROOT/public/system/, which is both persistent and private (shouldn't be able to be enumerated on shared hosting).
You can configure it to produce thumbnails of your images if you wish.
And it can remove the images it manages when the associated model is destroyed - after your user downloads their PDF, and you delete the record from the database.
Prawn might not be appropriate, depending on the complexity of the PDFs you need to generate. If you have $$$, go for PrinceXML and the princely gem. I've had some success with wkhtmltopdf, which generates PDFs from a Webkit render of HTML/CSS - but it doesn't support any of the advanced page manipulation stuff that Prince does.
How would I store a pdf in my Rails app so that users can access/download them?
In my migration, would i i use the datatype t.binary?
Then in my controller/view, how should I present this data?
The answer here is probably it depends. Depends on the size and number of PDFs, where users have to be logged in to view them etc.
If you have lots of large PDFs, its probably not a good idea to store them in the database - just store them on the filesystem and store a file location in the database model.
If you do want to store them in the database, then using a binary column is the way to go.
If users don't have to be logged in to download the PDF's, then you could just place them into the public folder (inside a subfolder) and generate links to them for download - then your controller would only need to generate a link to a static PDF file, and the front end webserver will serve them up automatically without using a Rails process.
I've heard good things about Paperclip, which is a way of transparently handling this stuff - storing files on the filesystem, with a reference to that file location in the database.
This question probably isn't rails specific, but probably best way to do it is to generate the pdf and store them on your filesystem, then in your database keep a record of filenames and a date of when they were created (to delete old ones if you need to).