View Source EctoShorts.CommonChanges (ecto_shorts v2.4.0)

CommonChanges is a collection of functions to help with managing and creating our &changeset/2 function in our schemas.

Preloading associations on change

Often times we want to be able to change an association with (put/cast)_assoc, but we have an awkwardness of having to use a preload in a spot to do this. We can aleviate that by doing the following:

defmodule MyApp.Accounts.User do
  def changeset(changeset, params) do
    changeset
      |> cast([:name, :email])
      |> validate_required([:name, :email])
      |> EctoShorts.CommonChanges.preload_change_assoc(:address)
  end
end

Doing this allows us to then pass address in via a map, or even using the struct from the database directly to add as a relation

Validating relation is passed in somehow

We can validate for a relation being passed in via id or by using our preload_change_assoc by doing the following:

defmodule MyApp.Accounts.User do
  def changeset(changeset, params) do
    changeset
      |> cast([:name, :email, :address_id])
      |> validate_required([:name, :email])
      |> EctoShorts.CommonChanges.preload_change_assoc(:address,
        required_when_missing: :address_id
      )
  end
end

Conditional functions

We can also run functions when something happens by defining conditional functions like so:

defmodule MyApp.Accounts.User do
  alias EctoShorts.CommonChanges

  def changeset(changeset, params) do
    changeset
      |> cast([:name, :email, :address_id])
      |> validate_required([:name, :email])
      |> CommonChanges.put_when(
        &CommonChanges.changeset_field_nil?(&1, :email),
        &put_change(&1, :email, "some_default@gmail.com")
      )
  end
end

Summary

Functions

Checks if field on changeset is empty list in data or changes

Checks if field on changeset is nil in data or changes

This function is the primary use function Preloads changeset assoc if change is made and then and put_or_cast's it

Preloads a changesets association

Determines put or cast on association with some special magic

Run's changeset function if when function returns true

Functions

Link to this function

changeset_field_empty?(changeset, key)

View Source
@spec changeset_field_empty?(Ecto.Changeset.t(), atom()) :: boolean()

Checks if field on changeset is empty list in data or changes

Link to this function

changeset_field_nil?(changeset, key)

View Source
@spec changeset_field_nil?(Ecto.Changeset.t(), atom()) :: boolean()

Checks if field on changeset is nil in data or changes

Link to this function

preload_change_assoc(changeset, key)

View Source
@spec preload_change_assoc(Ecto.Changeset.t(), atom()) :: Ecto.Changeset.t()
Link to this function

preload_change_assoc(changeset, key, opts)

View Source
@spec preload_change_assoc(Ecto.Changeset.t(), atom(), keyword()) ::
  Ecto.Changeset.t()

This function is the primary use function Preloads changeset assoc if change is made and then and put_or_cast's it

Example

iex> CommonChanges.preload_change_assoc(changeset, :my_relation) iex> CommonChanges.preload_change_assoc(changeset, :my_relation, repo: MyApp.OtherRepo) iex> CommonChanges.preload_change_assoc(changeset, :my_relation, required: true) iex> CommonChanges.preload_change_assoc(changeset, :my_relation, required_when_missing: :my_relation_id)

Link to this function

preload_changeset_assoc(changeset, key, opts \\ [])

View Source
@spec preload_changeset_assoc(Ecto.Changeset.t(), atom(), keyword()) ::
  Ecto.Changeset.t()

Preloads a changesets association

Link to this function

put_or_cast_assoc(changeset, key, opts \\ [])

View Source
@spec put_or_cast_assoc(Ecto.Changeset.t(), atom(), Keyword.t()) :: Ecto.Changeset.t()

Determines put or cast on association with some special magic

If you pass a many to many relation only a list of id's it will count that as a member_update and remove or add members to the relations list

E.G. User many_to_many Fruit

This would update the user to have only fruits with id 1 and 3

CommonChanges.put_or_cast_assoc(change(user, fruits: [%{id: 1}, %{id: 3}]), :fruits)
Link to this function

put_when(changeset, when_func, change_func)

View Source

Run's changeset function if when function returns true