Exporting files to Supabase Buckets in Ruby
Supabase provides a storage solution through its bucket system. In this DevTip, we'll explore how to export files to Supabase storage buckets using Ruby, making it easy to manage and serve files in your applications.
Prerequisites
Before we begin, ensure you have:
- Ruby installed (version 2.7 or higher)
- A Supabase account
- Basic familiarity with Ruby programming
Setting up your environment
First, create a new Ruby project and add the required dependencies:
mkdir supabase-storage-demo
cd supabase-storage-demo
bundle init
Add the Supabase Ruby client to your Gemfile:
source 'https://rubygems.org'
gem 'supabase'
Install the dependencies:
bundle install
Configuration
Store your Supabase credentials securely using environment variables:
client = Supabase.create_client(
ENV['SUPABASE_URL'],
ENV['SUPABASE_ANON_KEY']
)
Never commit your Supabase credentials directly in your code.
Connecting to Supabase
Create a new Ruby file and establish the connection to Supabase:
require 'supabase'
client = Supabase.create_client(
'YOUR_SUPABASE_URL',
'YOUR_SUPABASE_ANON_KEY'
)
Creating a storage bucket
Before uploading files, you need to create a storage bucket:
def create_bucket(supabase, bucket_name)
begin
supabase.storage.create_bucket(bucket_name, public: true)
puts "Bucket '#{bucket_name}' created"
rescue => e
puts "Error creating bucket: #{e.message}"
end
end
create_bucket(supabase, 'my-files')
Understanding bucket permissions
When working with Supabase storage, it's important to understand the permission model:
-
Bucket Operations: Creating, deleting, and modifying buckets typically requires admin privileges. These operations should be performed during setup or through admin interfaces.
-
File Operations: File uploads, downloads, and deletions are controlled by Row Level Security (RLS) policies. By default:
- Public buckets allow anyone to read files
- File modifications (upload/delete) require authentication
- Custom policies can be set for more granular control
Here's how to set up a basic RLS policy for your bucket in the Supabase dashboard:
-- Allow authenticated users to upload files
CREATE POLICY "Allow authenticated uploads"
ON storage.objects
FOR INSERT
TO authenticated
WITH CHECK (bucket_id = 'my-files');
-- Allow public file downloads
CREATE POLICY "Allow public downloads"
ON storage.objects
FOR SELECT
TO public
USING (bucket_id = 'my-files');
Adjust these policies based on your application's security requirements.
Exporting files to Supabase
Export files to your Supabase bucket:
def export_file(client, bucket_name, file_path, destination_path)
begin
File.open(file_path, 'rb') do |file|
response = client.storage
.from(bucket_name)
.upload(destination_path, file)
puts "File uploaded"
puts "Public URL: #{get_public_url(client, bucket_name, destination_path)}"
end
rescue Supabase::Error => e
puts "Supabase error: #{e.message}"
rescue Errno::ENOENT => e
puts "File not found: #{e.message}"
rescue StandardError => e
puts "Unexpected error: #{e.message}"
end
end
def get_public_url(supabase, bucket_name, file_path)
supabase.storage.from(bucket_name).get_public_url(file_path)
end
Usage example:
# Export a single file
export_file(supabase, 'my-files', 'path/to/local/image.jpg', 'uploads/image.jpg')
# Export multiple files
files = Dir.glob('path/to/files/*')
files.each do |file|
destination = "uploads/#{File.basename(file)}"
export_file(supabase, 'my-files', file, destination)
end
Error handling and validation
Implement error handling and file validation:
def validate_and_export_file(supabase, bucket_name, file_path, destination_path)
unless File.exist?(file_path)
raise "File not found: #{file_path}"
end
file_size = File.size(file_path)
max_size = 50 * 1024 * 1024 # 50MB limit
if file_size > max_size
raise "File exceeds maximum size of 50MB"
end
allowed_types = %w[.jpg .jpeg .png .pdf .doc .docx]
unless allowed_types.include?(File.extname(file_path).downcase)
raise "Invalid file type. Allowed types: #{allowed_types.join(', ')}"
end
export_file(supabase, bucket_name, file_path, destination_path)
end
Managing uploaded files
List and manage files in your bucket:
def list_files(supabase, bucket_name, path = '')
response = supabase.storage.from(bucket_name).list(path)
if response.error.nil?
response.data.each do |file|
puts "Name: #{file['name']}"
puts "Size: #{file['metadata']['size']} bytes"
puts "Last modified: #{file['metadata']['lastModified']}"
puts "---"
end
else
puts "Error listing files: #{response.error}"
end
end
def delete_file(supabase, bucket_name, file_path)
response = supabase.storage.from(bucket_name).remove([file_path])
if response.error.nil?
puts "File deleted"
else
puts "Error deleting file: #{response.error}"
end
end
Use cases
- Uploading user-generated content
- Storing and serving application assets
- Creating backup systems
- Managing document libraries
- Handling media files for content management systems
Best practices
-
Use unique file names to prevent overwrites:
require 'securerandom' def generate_unique_filename(original_filename) extension = File.extname(original_filename) "#{SecureRandom.uuid}#{extension}" end
-
Implement proper error handling
-
Validate file types and sizes before upload
-
Use appropriate bucket permissions
-
Clean up temporary files after upload
-
Configure CORS if uploading from browsers:
-- In Supabase Dashboard SQL Editor ALTER BUCKET "my-files" ENABLE CORS 'http://localhost:3000';
-
Use structured paths for better organization:
# Example: uploads/2024/01/unique-filename.jpg def generate_storage_path(filename) date = Time.now "uploads/#{date.year}/#{date.month}/#{filename}" end
Conclusion
Supabase storage buckets provide a reliable solution for file management in Ruby applications. With the examples provided, you can implement a robust file export system that handles various file types and sizes.
For more advanced media processing needs, consider using Transloadit alongside Supabase:
- Image Processing: Automatic image optimization, resizing, and format conversion
- Video Handling: Transcoding, thumbnails, and adaptive streaming
- Audio Processing: Format conversion, waveform generation, and audio normalization
- Document Processing: PDF generation, OCR, and document previews
- AI Processing: Face detection, object recognition, and content moderation
Check out Transloadit's Ruby SDK to supercharge your file processing pipeline while using Supabase for storage.