While the Paperclip gem is awesome for most Rails use cases, it doesn’t have support for saving files to a database. In some scenarios, access to the filesystem or an external service like Amazon S3 isn’t feasible. Or maybe you just want to put your files in the database.
As it happens, file upload in vanilla Rails is simple.
First, create a model that will store the file. Give it the following attributes:
Note: To quickly scaffold the model to save some keystrokes, do
rails g scaffold document filename:string content_type:string file_contents:binary in your terminal.
Here’s the code for the model and migration:
Next, add a file input to the model’s form.
Next, you need to make sure you allow the file as a parameter so you can use it in the model.
Finally, update the model to read and save the file. In Rails, a file input is passed in as an UploadedFile that can be treated like a normal file. I prefer to save the file in the model initialization.
So now you have an application that users can upload files to, but they still can’t download them. We can make the
show action of the
documents_controller download the file. To do so, simply send the file data saved in the document.
You’ve now seen everything it takes to make file upload and download work in vanilla Rails! If you want to do validations on attributes like file size, you’ll need to make a slight change to the initialization in the model so the file object can be accessed in the validations.
I’ve created an example file upload application showing everything in action together. The source is on GitHub.
If you enjoyed this article, follow me on Twitter for more like it. Happy hacking!