View Source EctoShorts.Actions (ecto_shorts v2.4.0)
Actions for CRUD in ecto, these can be used by all schemas/queries
Generally we can define our contexts to be very reusable by creating them to look something like this:
defmodule MyApp.Accounts do
alias EctoShorts.Actions
alias MyApp.Accounts.User
def all_users(params), do: Actions.all(User, params)
def find_user(params), do: Actions.find(User, params)
end
We're then able to use this context with all filters that are
supported by EctoShorts.CommonFilters
without having to create new queries
def do_something do
MyApp.Accounts.all_user(%{
first_name: %{ilike: "john"},
age: %{gte: 18},
priority_level: 5,
address: %{country: "Canada"}
})
end
You can read more on reusable ecto code here
Supporting multiple Repos
To support multiple repos, what we can do is pass arguments to the last parameter
of most EctoShorts.Actions
calls
Example
defmodule MyApp.Accounts do
alias EctoShorts.Actions
alias MyApp.Accounts.User
@repo [repo: MyApp.Repo.Replica1]
def all_users(params), do: Actions.all(User, params, @repo)
def find_user(params), do: Actions.find(User, params, @repo)
end
Summary
Functions
Gets a collection of schemas from the database
Gets a collection of schemas from the database but allows for a filter or an options list.
Similar to all/2
but can also accept a keyword options list.
Creates a schema with given params. Can also accept a keyword options list.
Deletes a schema
Similar to delete/1
but can also accept a keyword options list.
Deletes a schema. Can also accept a keyword options list.
Finds a schema with matching params. Can also accept a keyword options list.
Finds a schema by params and updates it or creates with results of params/update_params merged. Can also accept a keyword options list.
Finds a schema by params and updates it or creates with results of params/update_params merged. Can also accept a keyword options list.
Finds a schema by params or creates one if it isn't found. Can also accept a keyword options list.
Accepts a list of schemas and attempts to find them in the DB. Any missing Schemas will be created. Can also accept a keyword options list.
Gets a schema from the database
Gets a collection of schemas from the database but allows for a filter
Updates a schema with given updates. Can also accept a keyword options list.
Types
@type aggregate_options() :: :avg | :count | :max | :min | :sum
@type opts() :: Keyword.t()
@type query() :: Ecto.Query.t() | Ecto.Schema.t() | module()
@type schema_list() :: [Ecto.Schema.t()]
@type schema_res() :: {:ok, Ecto.Schema.t()} | {:error, any()}
Functions
@spec aggregate( queryable :: query(), params :: filter_params(), agg_opts :: aggregate_options(), field :: atom(), opts() ) :: term()
Gets a collection of schemas from the database
Examples
iex> EctoSchemas.Actions.all(EctoSchemas.Accounts.User)
[]
@spec all(queryable :: query(), filter_params() | opts()) :: list()
Gets a collection of schemas from the database but allows for a filter or an options list.
Options
:repo
- A module that uses the Ecto.Repo Module.
Examples
iex> Enum.each(1..4, fn _ -> create_user() end)
iex> length(EctoSchemas.Actions.all(EctoSchemas.Accounts.User, first: 3)) === 3
true
iex> Enum.each(1..4, fn _ -> create_user() end)
iex> length(EctoSchemas.Actions.all(EctoSchemas.Accounts.User, repo: MyApp.MyRepoModule.Repo)) === 3
true
@spec all(queryable :: query(), params :: filter_params(), opts()) :: list()
Similar to all/2
but can also accept a keyword options list.
Options
:repo
- A module that uses the Ecto.Repo Module.
Examples
iex> Enum.each(1..4, fn _ -> create_user() end) iex> length(EctoSchemas.Actions.all(EctoSchemas.Accounts.User, first: 3, repo: MyApp.MyRepoModule.Repo)) === 3 true
@spec create(schema :: module(), params :: filter_params(), opts()) :: {:ok, Ecto.Schema.t()} | {:error, Ecto.Changeset.t()}
Creates a schema with given params. Can also accept a keyword options list.
Options
:repo
- A module that uses the Ecto.Repo Module.
Examples
iex> {:ok, schema} = EctoSchemas.Actions.create(EctoSchemas.Accounts.User, user_params(first_name: "TEST"))
iex> schema.first_name
"TEST"
iex> {:error, changeset} = EctoSchemas.Actions.create(EctoSchemas.Accounts.User, Map.delete(user_params(), :first_name))
iex> "can't be blank" in errors_on(changeset).first_name
true
Examples
iex> {:ok, schema} = EctoSchemas.Actions.create(EctoSchemas.Accounts.User, user_params(first_name: "TEST"), repo: MyApp.MyRepoModule.Repo)
iex> schema.first_name
true
@spec delete(schema_data :: Ecto.Schema.t() | schema_list() | module()) :: {:ok, Ecto.Schema.t()} | {:error, any()}
Deletes a schema
Examples
iex> user = create_user()
iex> {:ok, schema} = EctoSchemas.Actions.delete(user)
iex> schema.first_name === user.first_name
true
@spec delete(schema_data :: Ecto.Schema.t() | schema_list() | module(), opts()) :: {:ok, Ecto.Schema.t()} | {:error, any()}
@spec delete(schema :: module(), id :: integer()) :: {:ok, Ecto.Schema.t()} | {:error, any()}
Similar to delete/1
but can also accept a keyword options list.
Options
:repo
- A module that uses the Ecto.Repo Module.
Examples
iex> user = create_user()
iex> {:ok, schema} = EctoSchemas.Actions.delete(user, repo: MyApp.MyRepoModule.Repo)
iex> schema.first_name === user.first_name
true
@spec delete(schema :: module(), id :: integer(), opts()) :: {:ok, Ecto.Schema.t()} | {:error, any()}
Deletes a schema. Can also accept a keyword options list.
Options
:repo
- A module that uses the Ecto.Repo Module.
Examples
iex> user = create_user()
iex> {:ok, schema} = EctoSchemas.Actions.delete(EctoSchemas.Accounts.User, user.id)
iex> schema.first_name === user.first_name
true
iex> user = create_user()
iex> {:ok, schema} = EctoSchemas.Actions.delete(EctoSchemas.Accounts.User, user.id)
iex> schema.first_name === user.first_name
true
@spec find(queryable :: query(), params :: filter_params(), opts()) :: schema_res() | {:error, any()}
Finds a schema with matching params. Can also accept a keyword options list.
Options
:repo
- A module that uses the Ecto.Repo Module.
Examples
iex> user = create_user()
iex> {:ok, schema} = EctoSchemas.Actions.find(EctoSchemas.Accounts.User, first_name: user.first_name)
iex> schema.first_name === user.first_name
true
iex> user = create_user()
iex> {:ok, schema} = EctoSchemas.Actions.find(EctoSchemas.Accounts.User, first_name: user.first_name, repo: MyApp.MyRepoModule.Repo)
iex> schema.first_name === user.first_name
true
Finds a schema by params and updates it or creates with results of params/update_params merged. Can also accept a keyword options list.
Note: Relational filtering doesn't work on this function
Options
:repo
- A module that uses the Ecto.Repo Module.:replica
- If you don't want to perform any reads against your Primary, you can specify a replica to read from.
Examples
iex> {:ok, schema} = EctoSchemas.Actions.find_and_update(EctoSchemas.Accounts.User, %{email: "some_email"}, %{name: "great name"})
iex> {:ok, schema} = EctoSchemas.Actions.find_and_update(EctoSchemas.Accounts.User, %{email: "some_email"}, %{name: "great name}, repo: MyApp.MyRepoModule.Repo, replica: MyApp.MyRepoModule.Repo.replica())
Finds a schema by params and updates it or creates with results of params/update_params merged. Can also accept a keyword options list.
Note: Relational filtering doesn't work on this function
Options
:repo
- A module that uses the Ecto.Repo Module.:replica
- If you don't want to perform any reads against your Primary, you can specify a replica to read from.
Examples
iex> {:ok, schema} = EctoSchemas.Actions.find_and_upsert(EctoSchemas.Accounts.User, %{email: "some_email"}, %{name: "great name"})
iex> {:ok, schema} = EctoSchemas.Actions.find_and_upsert(EctoSchemas.Accounts.User, %{email: "some_email"}, %{name: "great name}, repo: MyApp.MyRepoModule.Repo, replica: MyApp.MyRepoModule.Repo.replica())
@spec find_or_create(query(), map(), opts()) :: {:ok, Ecto.Schema.t()} | {:error, Ecto.Changeset.t()}
Finds a schema by params or creates one if it isn't found. Can also accept a keyword options list.
Note: Relational filtering doesn't work on this function
Options
:repo
- A module that uses the Ecto.Repo Module.:replica
- If you don't want to perform any reads against your Primary, you can specify a replica to read from.
Examples
iex> {:ok, schema} = EctoSchemas.Actions.find_or_create(EctoSchemas.Accounts.User, %{name: "great name"})
iex> {:ok, schema} = EctoSchemas.Actions.find_or_create(EctoSchemas.Accounts.User, %{name: "great name"}, repo: MyApp.MyRepoModule.Repo, replica: MyApp.MyRepoModule.Repo.replica())
@spec find_or_create_many( query(), [map()], opts() ) :: {:ok, [Ecto.Schema.t()]} | {:error, [Ecto.Changeset.t()]}
Accepts a list of schemas and attempts to find them in the DB. Any missing Schemas will be created. Can also accept a keyword options list.
Note: Relational filtering doesn't work on this function
Options
:repo
- A module that uses the Ecto.Repo Module.:replica
- If you don't want to perform any reads against your Primary, you can specify a replica to read from.
Examples
iex> {:ok, records} = EctoSchemas.Actions.find_or_create_many(EctoSchemas.Accounts.User, [%{name: "foo"}, %{name: "bar}]) iex> length(records) === 2
@spec get(queryable :: query(), id :: term(), options :: Keyword.t()) :: Ecto.Schema.t() | nil
Gets a schema from the database
Examples
iex> user = create_user()
iex> %{id: id} = EctoSchemas.Actions.get(EctoSchemas.Accounts.User, user.id)
iex> id === user.id
true
iex> EctoSchemas.Actions.get(EctoSchemas.Accounts.User, 2504390) # ID nonexistant
nil
@spec stream(queryable :: query(), params :: filter_params(), opts()) :: Enum.t()
Gets a collection of schemas from the database but allows for a filter
@spec update( schema :: Ecto.Schema.t() | module(), id :: pos_integer() | String.t(), updates :: map() | Keyword.t(), opts() ) :: {:ok, Ecto.Schema.t()} | {:error, Ecto.Changeset.t()}
@spec update( schema :: Ecto.Schema.t() | module(), schema_data :: Ecto.Schema.t(), updates :: map() | Keyword.t(), opts() ) :: {:ok, Ecto.Schema.t()} | {:error, Ecto.Changeset.t()}
Updates a schema with given updates. Can also accept a keyword options list.
Options
:repo
- A module that uses the Ecto.Repo Module.:replica
- If you don't want to perform any reads against your Primary, you can specify a replica to read from.
Examples
iex> user = create_user()
iex> {:ok, schema} = EctoSchemas.Actions.update(EctoSchemas.Accounts.User, user, first_name: user.first_name)
iex> schema.first_name === user.first_name
true
iex> user = create_user()
iex> {:ok, schema} = EctoSchemas.Actions.update(EctoSchemas.Accounts.User, 1, first_name: user.first_name, repo: MyApp.MyRepoModule.Repo, replica: MyApp.MyRepoModule.Repo.replica())
iex> schema.first_name === user.first_name
true