Skip to content

Latest commit

 

History

History
110 lines (85 loc) · 2.29 KB

using_with_ecto.md

File metadata and controls

110 lines (85 loc) · 2.29 KB

Using with ecto

After you finished Getting Started guide, you may be interested how to use this library with ecto. The general approach is to link your files to some database entries.

Defined schema

Suppose we have the following simple schema for users.

defmodule MyApp.User do
  use Ecto.Schema

  alias Ecto.Changeset

  schema "users" do
    field :username, :string
    timestamps()
  end

  def changeset(user, attrs) do
    user
    |> Changeset.cast(attrs, [:username])
    |> Changeset.validate_required([:username])
  end
end

And this is the module responsible for busyness logic.

defmodule MyApp.UserQueries do
  alias MyApp.{Repo, User}

  def create(attrs) do
    %User{}
    |> User.changeset(attrs)
    |> Repo.insert()
  end
end

Adding avatars to the schema

Now we want to be able to attach avatars. First we add :string field to the schema and modify MyApp.User.changeset/2 function.

defmodule MyApp.User do
  use Ecto.Schema

  alias Ecto.Changeset

  schema "users" do
    field :username, :string
    field :avatar, :string
    timestamps()
  end

  def changeset(user, attrs) do
    user
    |> Changeset.cast(attrs, [:username, :avatar])
    |> Changeset.validate_required([:username, :avatar])
  end
end

Handling avatar uploading

Then we add image processing logic to MyApp.UserQueries.

defmodule MyApp.UserQueries do
  alias MyApp.{Repo, User}

  def create(attrs) do
    with {:ok, filename} <- handle_image(attrs) do
      do_create(%{attrs | "avatar" => filename})
    end
  end

  # This function is responsible for actual image uploading.
  defp handle_image(%{"avatar" => %Plug.Upload{path: path}}) do
    %{filename: filename} = file = IVCU.File.from_path(path)

    with {:ok, _} <- IVCU.save(file, MyApp.Image) do
      {:ok, filename}
    end
  end

  defp handle_image(_) do
    {:error, :avatar_is_missing}
  end

  # Here we moved actual call database interaction into a separate
  # function.
  defp do_create(attrs) do
    %User{}
    |> User.changeset(attrs)
    |> Repo.insert()
  end
end

Warning {: .warning}

Of cause you can implement more sophisticated validations on the input. The code above provided for demonstration purposes only.