Packages

A simple module to clear up the boilerplate of CRUD resources in Phoenix context files.

Current section

Files

Jump to
ecto_cooler lib resource_functions.ex
Raw

lib/resource_functions.ex

defmodule EctoCooler.ResourceFunctions do
@moduledoc false
import Ecto.Query
@spec change(module, Ecto.Schema.t(), map() | Keyword.t()) :: Ecto.Changeset.t()
def change(schema, changeable, changes) do
changeable
|> schema.changeset(normalize_attributes(changes))
end
@spec changeset(module) :: Ecto.Changeset.t()
def changeset(schema) do
schema.changeset(struct(schema), %{})
end
@spec create(Ecto.Repo.t(), module, map() | Keyword.t()) ::
{:ok, Ecto.Schema.t()} | {:error, Ecto.Changeset.t()}
def create(repo, schema, attributes) do
schema
|> struct()
|> schema.changeset(normalize_attributes(attributes))
|> repo.insert([])
end
@spec create!(Ecto.Repo.t(), module, map() | Keyword.t()) :: Ecto.Schema.t()
def create!(repo, schema, attributes) do
schema
|> struct()
|> schema.changeset(normalize_attributes(attributes))
|> repo.insert!([])
end
@spec delete(Ecto.Repo.t(), Ecto.Schema.t()) ::
{:ok, Ecto.Schema.t()} | {:error, Ecto.Changeset.t()}
def delete(repo, deletable) do
deletable
|> repo.delete([])
end
@spec delete!(Ecto.Repo.t(), Ecto.Schema.t()) :: Ecto.Schema.t()
def delete!(repo, deletable) do
deletable
|> repo.delete!([])
end
@spec get(Ecto.Repo.t(), module, term(), Keyword.t()) :: Ecto.Schema.t() | nil
def get(repo, schema, id, options \\ []) do
preloads = Keyword.get(options, :preloads, [])
repo_opts = Keyword.delete(options, :preloads)
schema
|> preload(^preloads)
|> repo.get(id, repo_opts)
end
@spec get!(Ecto.Repo.t(), module, term(), Keyword.t()) :: Ecto.Schema.t()
def get!(repo, schema, id, options \\ []) do
preloads = Keyword.get(options, :preloads, [])
repo_opts = Keyword.delete(options, :preloads)
schema
|> preload(^preloads)
|> repo.get!(id, repo_opts)
end
@spec get_by(Ecto.Repo.t(), Ecto.Queryable.t(), Keyword.t() | map(), Keyword.t()) ::
Ecto.Schema.t() | nil
def get_by(repo, schema, attributes, options \\ []) do
preloads = Keyword.get(options, :preloads, [])
repo_opts = Keyword.delete(options, :preloads)
schema
|> preload(^preloads)
|> repo.get_by(attributes, repo_opts)
end
@spec get_by!(Ecto.Repo.t(), Ecto.Queryable.t(), Keyword.t() | map(), Keyword.t()) ::
Ecto.Schema.t()
def get_by!(repo, schema, attributes, options \\ []) do
preloads = Keyword.get(options, :preloads, [])
repo_opts = Keyword.delete(options, :preloads)
schema
|> preload(^preloads)
|> repo.get_by!(attributes, repo_opts)
end
@spec all(Ecto.Repo.t(), module, Keyword.t()) :: list(Ecto.Schema.t())
def all(repo, schema, options \\ []) do
preloads = Keyword.get(options, :preloads, [])
order_opts = Keyword.get(options, :order_by, [])
conditions = Keyword.get(options, :where, [])
schema
|> maybe_preload(preloads)
|> maybe_order_by(order_opts)
|> maybe_where(conditions)
|> repo.all([])
end
@spec update(Ecto.Repo.t(), module, Ecto.Schema.t(), map() | Keyword.t()) ::
{:ok, Ecto.Schema.t()} | {:error, Ecto.Changeset.t()}
def update(repo, schema, updateable, attributes) do
updateable
|> schema.changeset(normalize_attributes(attributes))
|> repo.update([])
end
@spec update!(Ecto.Repo.t(), module, Ecto.Schema.t(), map() | Keyword.t()) :: Ecto.Schema.t()
def update!(repo, schema, updateable, attributes) do
updateable
|> schema.changeset(normalize_attributes(attributes))
|> repo.update!([])
end
# ---------------------------------------------------------------------------
# Private helpers
# ---------------------------------------------------------------------------
defp maybe_preload(query, []), do: query
defp maybe_preload(query, preloads), do: preload(query, ^preloads)
defp maybe_order_by(query, []), do: query
defp maybe_order_by(query, opts), do: order_by(query, ^opts)
defp maybe_where(query, []), do: query
defp maybe_where(query, conditions), do: where(query, ^conditions)
defp normalize_attributes(attrs) when is_list(attrs), do: Enum.into(attrs, %{})
defp normalize_attributes(attrs), do: attrs
end