Phoenix 框架回调

Phoenix Framework callbacks

Phoenix Framework 是否使用任何类型的回调过滤器,例如 Rails 中的回调过滤器?我知道可以验证变更集,但我正在寻找实现 before_createbefore_saveafter_commit.

等操作的方法

Ecto 做了:https://hexdocs.pm/ecto/#!Ecto.Model.Callbacks.html

它们与 Rails 有明显不同:它们接收并且必须 return 变更集并且必须用于数据一致性(不要用它们发送电子邮件等等) .

从 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 makes it possible to pack operations that should be performed together (in a single database transaction) and gives a way to introspect the queued operations without actually performing them. Each operation is given a name that is unique and will identify its result or will help to identify the place of failure in case it occurs. So whenever you want a group of data related operations to happen at once you could use Multi, both before_ and after_ callbacks can be substituted here.

一个例子是

  # 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

来源: