Uploading Large Files in Ruby on Rails
π Uploading Large Files in Ruby on Rails: A Complete Guide
Managing large file uploads can be challenging in web development, especially when working with Ruby on Rails. But donβt worry β in this blog, weβll explore various options to handle large file uploads efficiently, with examples to make it crystal clear. Letβs dive in! π
π Why Large File Uploads Are Challenging
Large file uploads often require:
- Efficient memory usage.
- Handling timeouts.
- Secure file handling.
- Compatibility with cloud storage.
Thankfully, Ruby on Rails provides several options to handle these challenges. Letβs explore them one by one! π΅οΈβββ
π Option 1: Direct Uploads to Cloud Storage
Direct uploads offload the burden from your Rails server by uploading files straight to cloud storage like AWS S3, GCS, or Azure Blob Storage.
Implementation with Active Storage
- Add Active Storage to your app:
rails active_storage:install rails db:migrate
- Configure cloud storage in
config/storage.yml
:amazon: service: S3 access_key_id: <%= ENV["AWS_ACCESS_KEY_ID"] %> secret_access_key: <%= ENV["AWS_SECRET_ACCESS_KEY"] %> region: <%= ENV["AWS_REGION"] %> bucket: <%= ENV["AWS_BUCKET"] %>
- Enable direct uploads in the form:
<%= form_with(model: @file, url: files_path, method: :post, multipart: true) do |form| %> <%= form.file_field :attachment, direct_upload: true %> <%= form.submit "Upload" %> <% end %>
Benefits
- π Speed: Files donβt pass through your server.
- π Scalability: Works seamlessly with large files.
- π Security: Uses signed URLs for secure uploads.
βοΈ Option 2: Chunked File Uploads
Chunked uploads split large files into smaller parts, uploading them sequentially or in parallel. This reduces memory usage and minimizes upload failures.
Implementation with JavaScript
-
Use a library like FineUploader or Dropzone.js.
- Create an endpoint in Rails:
class UploadsController < ApplicationController def create uploaded_file = params[:file] File.open(Rails.root.join('uploads', uploaded_file.original_filename), 'wb') do |file| file.write(uploaded_file.read) end render json: { message: "File uploaded successfully!" }, status: :ok end end
- Configure the frontend to handle chunks:
const uploader = new FineUploader({ request: { endpoint: "/uploads", }, chunking: { enabled: true, partSize: 2 * 1024 * 1024, // 2 MB }, });
Benefits
- π‘ Resilience: Can resume uploads if interrupted.
- π§΅ Memory Efficiency: Small chunks reduce memory load.
π Option 3: Background Processing
Use background jobs for processing large uploads asynchronously. This ensures the server remains responsive during uploads.
Implementation with Sidekiq
- Add Sidekiq to your app:
bundle add sidekiq
- Create a background job:
class FileUploadJob < ApplicationJob queue_as :default def perform(file) # Process the file (e.g., move to storage, resize images) end end
- Enqueue the job after file upload:
def create file = params[:file] FileUploadJob.perform_later(file.path) render json: { message: "File will be processed soon!" }, status: :accepted end
Benefits
- π Scalability: Handles heavy processing without blocking the main thread.
- π Deferred Processing: Keeps the user interface responsive.
π¦ Option 4: Using External Gems
Some gems make handling large uploads a breeze. Letβs explore a popular one:
Shrine
Shrine is a flexible and lightweight file upload solution.
- Add Shrine to your Gemfile:
gem 'shrine'
- Set up the uploader:
class FileUploader < Shrine plugin :presign_endpoint end
- Enable presigned uploads:
class UploadsController < ApplicationController def presign presign_data = FileUploader.presign("cache") render json: presign_data end end
Benefits
- π§© Modular: Highly customizable.
- π Detailed Support: Supports multiple storage backends.
π‘ Pro Tips for Large File Uploads
- Optimize File Size: Encourage users to compress files before upload.
- Use CDN: Deliver files through a CDN for faster access.
- Implement Progress Indicators: Keep users informed with upload progress bars.
π Conclusion
Uploading large files in Ruby on Rails can be made efficient with the right approach. Whether you choose direct uploads, chunking, background processing, or an external gem like Shrine, Rails has you covered. π
Got questions or suggestions? Drop a comment below! π¬ Happy coding! π¨βπ»π©βπ»
© Lakhveer Singh Rajput - Blogs. All Rights Reserved.