Crudry v2.4.0 Crudry.Context View Source
Generates CRUD functions to DRY Phoenix Contexts.
Assumes
Ecto.Repo
is being used as the repository.Uses the Ecto Schema source name to generate the pluralized name for the functions, and the module name to generate the singular name.
This follows the same pattern as the Mix.Tasks.Phx.Gen.Context, so it should be straightforward to replace Phoenix's auto-generated functions with Crudry.
Usage
To generate CRUD functions for a given schema, simply do
defmodule MyApp.MyContext do
alias MyApp.Repo
alias MyApp.MySchema
require Crudry.Context
Crudry.Context.generate_functions MySchema
end
And the context will have all these functions available:
defmodule MyApp.MyContext do
alias MyApp.Repo
alias MyApp.MySchema
require Crudry.Context
## Get functions
def get_my_schema(id) do
Repo.get(MySchema, id)
end
def get_my_schema!(id) do
Repo.get!(MySchema, id)
end
def get_my_schema_with_assocs(id, assocs) do
MySchema
|> Repo.get(id)
|> Repo.preload(assocs)
end
def get_my_schema_with_assocs!(id, assocs) do
MySchema
|> Repo.get!(id)
|> Repo.preload(assocs)
end
def get_my_schema_by(clauses) do
Repo.get_by(MySchema, clauses)
end
def get_my_schema_by!(clauses) do
Repo.get_by!(MySchema, clauses)
end
def get_my_schema_by_with_assocs(clauses, assocs) do
MySchema
|> Repo.get_by(clauses)
|> Repo.preload(assocs)
end
def get_my_schema_by_with_assocs!(clauses, assocs) do
MySchema
|> Repo.get_by!(clauses)
|> Repo.preload(assocs)
end
## List functions
def list_my_schemas() do
Repo.all(MySchema)
end
def list_my_schemas(opts) do
MySchema
|> Crudry.Query.list(opts)
|> Repo.all()
end
def list_my_schemas_with_assocs(assocs) do
MySchema
|> Repo.all()
|> Repo.preload(assocs)
end
def list_my_schemas_with_assocs(assocs, opts) do
MySchema
|> Crudry.Query.list(opts)
|> Repo.all()
|> Repo.preload(assocs)
end
def filter_my_schemas(filters) do
MySchema
|> Crudry.Query.filter(filters)
|> Repo.all()
end
def search_my_schemas(search_term) do
module_fields = MySchema.__schema__(:fields)
MySchema
|> Crudry.Query.search(search_term, module_fields)
|> Repo.all()
end
def count_my_schemas(field \\ :id) do
Repo.aggregate(MySchema, :count, field)
end
## Create functions
def create_my_schema(attrs) do
%MySchema{}
|> MySchema.changeset(attrs)
|> Repo.insert()
end
def create_my_schema!(attrs) do
%MySchema{}
|> MySchema.changeset(attrs)
|> Repo.insert!()
end
## Update functions
def update_my_schema(%MySchema{} = my_schema, attrs) do
my_schema
|> MySchema.changeset(attrs)
|> Repo.update()
end
def update_my_schema!(%MySchema{} = my_schema, attrs) do
my_schema
|> MySchema.changeset(attrs)
|> Repo.update!()
end
def update_my_schema_with_assocs(%MySchema{} = my_schema, attrs, assocs) do
my_schema
|> Repo.preload(assocs)
|> MySchema.changeset(attrs)
|> Repo.update()
end
def update_my_schema_with_assocs!(%MySchema{} = my_schema, attrs, assocs) do
my_schema
|> Repo.preload(assocs)
|> MySchema.changeset(attrs)
|> Repo.update!()
end
## Delete functions
def delete_my_schema(%MySchema{} = my_schema) do
my_schema
|> Ecto.Changeset.change()
|> check_assocs([])
|> Repo.delete()
end
def delete_my_schema!(%MySchema{} = my_schema) do
my_schema
|> Ecto.Changeset.change()
|> check_assocs([])
|> Repo.delete!()
end
# Function to check no_assoc_constraints, always generated.
defp check_assocs(changeset, nil), do: changeset
defp check_assocs(changeset, constraints) do
Enum.reduce(constraints, changeset, fn i, acc -> Ecto.Changeset.no_assoc_constraint(acc, i) end)
end
end
Link to this section Summary
Link to this section Functions
Sets default options for the context.
Options
:create
- the name of the changeset function used in thecreate
function. Defaults to:changeset
.:update
- the name of the changeset function used in theupdate
function. Defaults to:changeset
.:only
- list of functions to be generated. If not empty, functions not specified in this list are not generated. Defaults to[]
.:except
- list of functions to not be generated. If not empty, only functions not specified in this list will be generated. Defaults to[]
.The accepted values for
:only
and:except
are:[:get, :list, :count, :search, :filter, :create, :update, :delete]
.
Examples
iex> Crudry.Context.default create: :create_changeset, update: :update_changeset
:ok
iex> Crudry.Context.default only: [:create, :list]
:ok
iex> Crudry.Context.default except: [:get!, :list, :delete]
:ok
Generates CRUD functions for the schema_module
.
Custom options can be given. To see the available options, refer to the documenation of Crudry.Context.default/1
.
There is also one extra option that cannot be set by default:
check_constraints_on_delete
- list of associations that must be empty to allow deletion.Ecto.Changeset.no_assoc_constraint
will be called for each association before deleting. Defaults to[]
.
Examples
Suppose we want to implement basic CRUD functionality for a User schema, exposed through an Accounts context:
defmodule MyApp.Accounts do
alias MyApp.Repo
require Crudry.Context
# Assuming Accounts.User implements a `changeset/2` function, used both to create and update a user.
Crudry.Context.generate_functions Accounts.User
end
Now, suppose the changeset for create and update are different, and we want to delete the record only if the association has_many :assocs
is empty:
defmodule MyApp.MyContext do
alias MyApp.Repo
alias MyApp.MySchema
require Crudry.Context
Crudry.Context.generate_functions MySchema,
create: :create_changeset,
update: :update_changeset,
check_constraints_on_delete: [:assocs]
end