# Uploadex
Uploadex is an Elixir library for handling uploads using [Ecto](https://github.com/elixir-ecto/ecto) and [Arc](https://github.com/stavro/arc).
## Installation
The package can be installed by adding `uploadex` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:uploadex, "~> 0.0.1"}
]
end
```
## Usage
This library is built on top of [Arc](https://github.com/stavro/arc), so you can configure it normally.
To use the default configuration, storing to the disk, no configuration is needed.
Then, define your uploader:
```elixir
defmodule MyApp.MyUploader do
use Uploadex.Definition,
repo: MyApp.Repo
## Functions required for Uploadex.Definition
def base_directory do
Path.join(:code.priv_dir(:my_app), "static/")
end
def get_files(%MyApp.User{photo: photo}), do: photo
# For this example, we assume company has_many :photos, and each photo has a file field.
# For this to work properly, we will need cast_assoc :photos when inserting/updating a company.
def get_files(%MyApp.Company{} = company) do
company
|> MyApp.Repo.preload(:photos)
|> Map.get(:photos)
|> Enum.map(& &1.file)
end
## We can also define the functions for Arc.Definition here
def storage_dir(_version, {_file, %User{id: user_id}}) do
Path.join(base_directory(), "/uploads/users/\#{user_id}")
end
def storage_dir(_version, {_file, %Company{id: id}}) do
Path.join(base_directory(), "/uploads/companies/\#{id}")
end
end
```
In your schema, use the Ecto Type `Uploadex.Upload`:
```elixir
schema "users" do
field :name, :string
field :photo, Uploadex.Upload
end
# No special cast is needed, and casting does not have any side effects.
def create_changeset(%User{} = user, attrs) do
user
|> cast(attrs, [:name, :photo])
end
```
Now, you can use the `Uploadex` functions to handle your records with their files:
```elixir
defmodule MyApp.Accounts do
alias MyApp.Accounts.User
alias MyApp.MyUploader
def create_user(attrs) do
%User{}
|> User.create_changeset(attrs)
|> Uploadex.create_with_file(MyUploader)
end
def update_user(%User{} = user, attrs) do
user
|> User.update_changeset(attrs)
|> Uploadex.update_with_file(user, MyUploader)
end
def delete_user(%User{} = user) do
user
|> Ecto.Changeset.change()
|> Uploadex.delete_with_file(MyUploader)
end
end
```
For more flexibility, you can use the `Files` module directly.