Empower Your Rails App with CarrierWave: Effortless File Uploads
In this article, we will be looking in-depth at the file uploader CarrierWave which its magical features that empower it to be more effective. We will be looking at what is the CarrierWave, how to use it, and why it is better than ActiveStorage, and also dive into the cool features it provides.
CarrierWave — An file uploader
CarrierWave provides the functionality to upload files with extreme simplicity and flexibility. Let’s first see how to set up and use the Carrier Wave.
- Add this gem to your Gemfile and run the bundle:
gem ‘carrierwave’
- Now generates an uploader using the command:
rails generate uploader ProfilePic
. This will create an uploader in the uploader directory. - Then, mount the uploader with your model:
class User < ApplicationRecord
mount_uploader :profile_pic, ProfilePicUploader
end
# For multiple File Uploads
# 1. For databases with ActiveRecord json data type support (profile_pic:json)
class User < ApplicationRecord
mount_uploader :profile_pic, ProfilePicUploader
end
# 2. For databases with ActiveRecord json data type not support
class User < ApplicationRecord
mount_uploaders :profile_pic, AvatarUploader
serialize :profile_pic, JSON # If you use SQLite, add this line.
end
4. On the create page add the file_field:
<%= form_with(model: user) do |form| %>
<% if user.errors.any? %>
<div style="color: red">
<h2><%= pluralize(user.errors.count, "error") %> prohibited this user from being saved:</h2>
<ul>
<% user.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>
<div>
<%= form.label :profile_pic, style: "display: block" %>
<%= form.file_field :profile_pic %>
</div>
<!-- Remaining Fields -->
<div>
<%= form.submit %>
</div>
<% end %>
5. Also we need to change our show page to seed the image using the predefined method url
:
<div id="<%= dom_id travel_package %>">
<p>
<strong>Profile Picture:</strong>
<%= image_tag(user.profile_pic.url) %>
</p>
<!-- Remaining Fields -->
</div>
That’s it! we have now used CarrierWave as our file uploader, with exciting new features.
Useful Features & Methods—
Below are some useful features and methods:
user.profile_pic.url # => '/url/to/file.png'
user.profile_pic.current_path # => 'path/to/file.png'
user.profile_pic_identifier # => 'file.png'
user.profile_pic.file.nil? # => to check file uploaded or not
# uploader features
class ProfilePicUploader < CarrierWave::Uploader::Base
# It will create the thumnail version of the image
# user.thumbnail.url => '/url/to/thumb_my_file.png'
include CarrierWave::MiniMagick
process resize_to_fit: [800, 800]
version :thumbnail do
process resize_to_fill: [200,200]
end
# Storage can be local (file), fog, azure, etc. If using cloud service
# that can be set in the carrierwave.rb initializer file with the access key
# and all, but with the required gem.
storage :file
# storage :azure
# Change file storage directory
def store_dir
'public/my/upload/directory'
end
# Change cache directory
def cache_dir
'/tmp/projectname-cache'
end
# Change filename
def filename
"#{file.model.name}.#{file.extension}" # If you upload 'file.jpg', you'll get 'name.jpg'
end
# Allowed extension list
def extension_allowlist
%w(jpg jpeg gif png)
end
# Allowed content type
def content_type_allowlist
/image\/
end
# Deny Content Type
def content_type_denylist
['application/text', 'application/json']
end
end
Many more cool features are very helpful so you can go in-depth at this.
Conclusion
Though Active Storage has been the default file uploader for the Rails but offers quite limited features and flexibility. So, if we just need simple file uploading in the project we can continue with Active Record but if we want to do more changes on the go with the files and provide some more interesting features hassle-free the best option would be CarrierWave.