Skip to main content
Version: 0.3

Uploading files

Marten gives you the ability to interact with uploaded files. These files are made available with each HTTP request object, and it is also possible to validate them using schemas. The following document explains how to expect and manipulate uploaded files, and what are their associated characteristics.

Accessing uploaded files

Uploaded files are made available in the #data hash-like object of any HTTP request object (instance of Marten::HTTP::Request). These file objects are instances of the Marten::HTTP::UploadedFile class.

For example, you could access and process a file file originating from an HTML form using a handler like this:

class ProcessUploadedFileHandler < Marten::Handler
def post
file = request.data["file"].as(Marten::HTTP::UploadedFile)
respond "Processed file: #{file.filename}"
end
end

Marten::HTTP::UploadedFile objects give you access to the following key methods, which allow you to interact with the uploaded file and its content:

  • #filename returns the name of the uploaded file
  • #size returns the size of the uploaded file
  • #io returns a regular IO object allowing to read the content of the file and interact with it
Where are uploaded files stored?

All uploaded files are automatically persisted to a temporary file in the system's temporary directory (usually this corresponds to the /tmp folder).

Expecting uploaded files with schemas

If you use schemas to validate input data (such as form data), then it's worth noting that you can explicitly define that you expect files in the validated data. The simplest way to do that is to make use of the file schema field.

For example, you could define the following schema:

class UploadFileSchema < Marten::Schema
field :file, :file
end

And use it in a regular schema generic handler like this:

class UploadFileHandler < Marten::Handlers::Schema
schema UploadFileSchema
template_name "upload_file.html"
success_url "/"

def process_valid_schema
file = schema.validated_data["file"]
# Do something with the uploaded file...

super
end
end

The presence/absence of the file (and - optionally - some of its attributes) will be validated according to the schema definition when POST requests are processed by the handler.

Persisting uploaded files in model records

Models can define file fields and persist "references" of uploaded files in their rows. This allows "retaining" specific uploaded files and associating their references with specific model records.

For example, we could modify the handler in the previous section so that it persists and associate the uploaded file to a new Attachment record as follows:

class UploadFileHandler < Marten::Handlers::Schema
schema UploadFileSchema
template_name "upload_file.html"
success_url "/"

def process_valid_schema
file = schema.validated_data["file"]
Attachment.create!(file: file)

super
end
end

Here, the UploadFileHandler inherits from the Marten::Handlers::Schema generic handler. It would also make sense to leverage the Marten::Handlers::RecordCreate generic handler to process the schema and create the Attachment record at the same time.