Callbacks are completely removed from Ecto 2.0.
So, how to handle callbacks now ?. Here are two ways:
For before_ you can use Changeset . One of the reasons callbacks that were deleted was that many developers relied on callbacks in many cases where there would be enough change sets. So just apply the required function to your change set,
def changeset(post, params \\ :empty) do post |> cast(params, @required_params, @optional_params) |> validate_length(:title, min: 3) |> validate_length(:metadata, min: 3) |> implement_a_before_callback end def implement_a_before_callback(changeset)
Another way is to combine multiple repo operations using Ecto.Multi . From the documents
Ecto.Multi allows you to package operations that must be performed together (in the same transaction with the database), and allows you to analyze operations in a queue without actually executing them. Each operation is assigned a unique name and will identify its result or help determine the place of failure in case of its occurrence. Therefore, when you want a group of operations related to data to occur immediately, you can use Multi , here the before_ and after_ callbacks can be replaced.
An example would be
# In defmodule Service def password_reset(account, params) do Multi.new |> Multi.update(:account, Account.password_reset_changeset(account, params)) |> Multi.insert(:log, Log.password_reset_changeset(account, params)) |> Multi.delete_all(:sessions, assoc(account, :sessions)) end
Run it using
result = Repo.transaction(Service.password_reset(account, params))
You must remember that you must complete data-related queries and not perform other tasks, such as sending emails. To do this, you can simply combine the template with the result and perform the corresponding action. Let's sit that you want to send mail if the transaction was successful, and display some error message if not
case result do {:ok, %{account: account, log: log, sessions: sessions}} ->
A source: