Files in records, with Ecto: a column of type Storehouse.Ecto.File
(or a list of them), files put in a changeset with put_file/4, made
permanent when the record is saved, and deleted once nothing has them.
schema "users" do
field :name, :string
field :avatar, Storehouse.Ecto.File
end
def changeset(user, attrs, avatar) do
user
|> cast(attrs, [:name])
|> Storehouse.Ecto.put_file(:avatar, avatar, accept: Storehouse.Check.images(), max_bytes: 5_000_000)
endTemporary, then permanent
A file a person uploads for a form is temporary until the form is
saved: store it with cache: true (Storehouse.Live.allow/3 and
consume/3, Storehouse.store/2), and its key is under the temporary
prefix (Storehouse.cache_prefix/0). When the record is saved,
put_file/4 makes it permanent (Storehouse.promote/2): a copy in the
store (on S3, in the bucket), in the save's transaction. A form never
saved leaves its files under the prefix, where a lifecycle rule of the
bucket deletes them:
{"Rules": [{"ID": "storehouse-cache", "Status": "Enabled",
"Filter": {"Prefix": "cache/"},
"Expiration": {"Days": 1}}]}Replaced and deleted files
A file the record no longer has (replaced, removed, or the record
deleted) is deleted from the store once the database has the change:
insert/3, update/3 and delete/3 save and then delete them.
Inside a transaction of yours, use Repo as usual, and delete
replaced/2's files after your transaction commits: a rollback would
otherwise leave a record whose file is gone.
Summary
Functions
repo.delete/2, then the record's files are deleted from the store.
Inside a transaction, they are not: delete files/1's after it
commits.
Deletes files from the store (Storehouse.delete/2).
Every file of a record, in its fields of files.
repo.insert/2, as it is: the files are made permanent in its
transaction (put_file/4).
Puts a file (a Storehouse.File, a list of them for a list field, or
nil to remove it) in the changeset, checked, and made permanent when
the record is saved.
The files a saved changeset leaves behind: those its record had in a
field of files, and does not have after it. Delete them once the
transaction has committed (delete_files/2).
repo.update/2, then the files it replaced or removed are deleted from
the store. Inside a transaction, they are not: delete replaced/2's
after it commits.
Functions
@spec delete(module(), struct() | Ecto.Changeset.t(), keyword()) :: {:ok, struct()} | {:error, Ecto.Changeset.t()}
repo.delete/2, then the record's files are deleted from the store.
Inside a transaction, they are not: delete files/1's after it
commits.
@spec delete_files([Storehouse.File.t()], keyword()) :: :ok
Deletes files from the store (Storehouse.delete/2).
@spec files(struct()) :: [Storehouse.File.t()]
Every file of a record, in its fields of files.
@spec insert(module(), Ecto.Changeset.t(), keyword()) :: {:ok, struct()} | {:error, Ecto.Changeset.t()}
repo.insert/2, as it is: the files are made permanent in its
transaction (put_file/4).
@spec put_file( Ecto.Changeset.t(), atom(), Storehouse.File.t() | [Storehouse.File.t()] | nil, keyword() ) :: Ecto.Changeset.t()
Puts a file (a Storehouse.File, a list of them for a list field, or
nil to remove it) in the changeset, checked, and made permanent when
the record is saved.
Options
:accept- the types the field takes (Storehouse.Check.images()).:max_bytes,:max_pixels- the limits.:adapter- the store, to make it permanent. The default isStorehouse.adapter/0.
A file over a limit, or of a type not taken, is an error of the field
(validation: :storehouse, with the :reason).
@spec replaced(Ecto.Changeset.t(), struct()) :: [Storehouse.File.t()]
The files a saved changeset leaves behind: those its record had in a
field of files, and does not have after it. Delete them once the
transaction has committed (delete_files/2).
@spec update(module(), Ecto.Changeset.t(), keyword()) :: {:ok, struct()} | {:error, Ecto.Changeset.t()}
repo.update/2, then the files it replaced or removed are deleted from
the store. Inside a transaction, they are not: delete replaced/2's
after it commits.