Attached (Attached v0.1.0)

Copy Markdown View Source

File attachments for Ecto schemas.

Changeset integration

Schemas that use Attached.Ecto.Schema automatically import put_attached/3 for use inside their changeset/2:

def changeset(user, attrs) do
  user
  |> cast(attrs, [:name])
  |> put_attached(:avatar, attrs["avatar"])
end

See Attached.Ecto.Changeset for details.

Querying

Attached.url(user, :avatar)
Attached.url(user, :avatar, :thumb)
Attached.attached?(user, :avatar)

Preloading

User |> Attached.with_attached(:avatar) |> Repo.all()

Summary

Functions

Returns true if the record has a file attached for the given field.

Returns a signed URL for a storage key.

Synchronously deletes the attachment: removes the original record, variant records, variant files, and all files from storage.

Enqueues an Oban job to purge the attachment asynchronously.

Creates an original and uploads the file to storage without a schema attachment context.

Returns the URL for an attachment, optionally for a named variant.

Returns an Ecto query with the attachment original preloaded.

Functions

attached?(record, field)

Returns true if the record has a file attached for the given field.

original_url(key)

Returns a signed URL for a storage key.

Useful when you have an original key and need a URL without going through url/2 or url/3 (which require a loaded schema record).

Returns {:ok, url} on success, or {:error, reason} if the storage backend cannot produce a URL (misconfigured backend, missing credentials, signing failure, etc.).

purge(record, field)

Synchronously deletes the attachment: removes the original record, variant records, variant files, and all files from storage.

purge_later(record, field)

Enqueues an Oban job to purge the attachment asynchronously.

upload_original(upload, opts)

Creates an original and uploads the file to storage without a schema attachment context.

Useful for endpoints that accept file uploads independently of a parent record (e.g. Trix inline image uploads before an article is saved).

Options:

  • :owner_table (required) — the table name the original will eventually belong to
  • :owner_field (required) — the FK column name (e.g. "attached_original_id")

Returns the inserted %Attached.Originals.Original{}.

url(record, field, variant \\ nil)

Returns the URL for an attachment, optionally for a named variant.

Attached.url(user, :avatar)
Attached.url(user, :avatar, :thumb)

Returns nil if no file is attached.

When called with a variant name, :variants must be preloaded on the original — either via Attached.with_attached/2 (recommended) or Repo.preload(record, avatar_attached_original: :variants). Raises ArgumentError otherwise.

with_attached(queryable, field)

Returns an Ecto query with the attachment original preloaded.

User |> Attached.with_attached(:avatar) |> Repo.all()