Latch::Uploader
Uploader module that handles file uploads with metadata extraction and location generation. Include this module in a struct or class.
struct ImageUploader
include Latch::Uploader
def generate_location(uploaded_file, metadata, **options) : String
date = Time.utc.to_s("%Y/%m/%d")
File.join("images", date, super)
end
end
ImageUploader.new("store").upload(uploaded_file)
# => Latch::StoredFile with id "images/2024/01/15/abc123.jpg"
Constructors
Instance methods
Extracts metadata from the IO. Override to add completely custom metadata
extraction outside of the extract DSL.
struct ImageUploader
include Latch::Uploader
def extract_metadata(
uploaded_file : Latch::UploadedFile,
metadata : MetadataHash? = nil,
**options,
) : MetadataHash
data = super
# Add custom metadata
data["custom"] = "value"
data
end
# Reopen the `StoredFile` class to add a method for the custom value.
class StoredFile
def custom : String
metadata["custom"].as(String)
end
end
end
Generates a unique location for the uploaded file. Override this in subclasses for custom locations.
struct ImageUploader
include Latch::Uploader
def generate_location(uploaded_file, metadata, **options) : String
File.join("images", super)
end
end
Generates a unique identifier for file locations. Override this in subclasses for custom filenames in the storage.
struct ImageUploader
include Latch::Uploader
def generate_uid(uploaded_file, metadata, **options) : String
"#{metadata["filename"]}-#{Time.local.to_unix}"
end
end
Macros
Registers an extractor for a given key.
struct PdfUploader
include Latch::Uploader
# Use a different MIME type extractor than the default one
extract mime_type, using: Latch::Extractor::MimeFromExtension
# Or use your own custom extractor to add arbitrary data
extract pages, using: MyNumberOfPagesExtractor
end
The result will then be added to the attachment's metadata after uploading:
invoice.pdf.pages
# => 24
Registers a processor and generates variant accessor methods on the
uploader's StoredFile. The processor must define a VARIANTS constant
listing its variant names.
struct AvatarUploader
include Latch::Uploader
process sizes, using: AvatarSizesProcessor
end
stored = AvatarUploader.store(uploaded_file)
AvatarUploader.process(stored)
stored.sizes_large.url # => "/uploads/abc123/sizes_large.jpg"
Configures the storage keys used by this uploader. Both cache and store
have defaults, so you only need to specify the ones you want to change.
struct ImageUploader
include Latch::Uploader
# Override both
storages cache: "tmp", store: "offsite"
end
struct VideoUploader
include Latch::Uploader
# Override only store; cache stays "cache"
storages store: "offsite"
end