Использует ли Phoenix Framework любые типы фильтров обратного вызова, например, найденные в Rails? Я знаю, что можно проверить набор изменений, но я ищу способы реализовать такие действия, как before_create
, before_save
и after_commit
.Обратные вызовы Phoenix Framework
ответ
Ecto делает: https://hexdocs.pm/ecto/#!Ecto.Model.Callbacks.html
Они красивые отличаются от тех, Rails: они получают и должны вернуться и ревизии должны быть использованы для обеспечения согласованности данных (не использовать их для отправки по электронной почте, а что нет).
Из Ecto 2.0 обратные вызовы были полностью удалены.
Итак, как обрабатывать обратные вызовы сейчас ?. Вот два способа:
Для обратных вызовов before_
вы можете использовать Changeset. Одна из причин обратных вызовов, которые были удалены из-за того, что многие разработчики полагались на обратные вызовы, во многих случаях, когда наборов изменений было бы достаточно. Так просто применить требуемую функцию к вашей ревизии,
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)
#Apply required actions and return Changeset
end
Другим способу, заключается в операцию объединения несколько репо вместе с использованием Ecto.Multi. В документах
Ecto.Multi позволяет выполнять операции, которые должны выполняться совместно (в одной транзакции с базой данных), и дает возможность подвергать операции в очереди без их фактического выполнения. Каждой операции присваивается уникальное имя и будет идентифицировать его результат или поможет определить место сбоя в случае его возникновения. Итак, всякий раз, когда вы хотите, чтобы группа операций, связанных с данными, происходила сразу, вы могли использовать
Multi
, здесь могут быть заменены как обратные вызовыbefore_
, так иafter_
.
Примером может быть
# 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
Выполнить это с помощью
result = Repo.transaction(Service.password_reset(account, params))
Вы должны помнить, что вы должны выполнить данные, связанные запросы, а не делать другие задачи, такие как отправить по электронной почте. Для этого вы можете просто совместить шаблон с результатом и выполнить соответствующее действие. Препятствует сидел ты хотел отправить почту, если транзакция прошла успешно, и отобразить какое-то сообщение об ошибке, если не
case result do
{:ok, %{account: account, log: log, sessions: sessions}} ->
# Operation was successful, perform actions like sending a mail
{:error, failed_operation, failed_value, changes_so_far} ->
# One of the operations failed. Raise error message
end
Источник:
Вот так! Принятый ответ устарел. – LukeS
страница говорит, что «Предупреждение: обратные вызовы Ecto устарели». Этот метод, вероятно, больше не рекомендуется – coderVishal
Да, и они полностью удалены из Ecto 2.0. Вот сообщение в блоге, объясняющее некоторые решения: http://blog.plataformatec.com.br/2015/12/ecto-v1-1-released-and-ecto-v2-0-plans/ –
Вот еще одна точка зрения (если вы родом из Rails): http://cloudless.pl/articles/ 11-model-callbacks-in-phoenix-ecto-and-rails –