我正在玩 Phoenix + Ecto,我偶然发现了一些对我来说不习惯的东西。
我有一个代表一个表格Invitation
。创建邀请函时,我们还需要创建一个User
显然我希望两者都发生在一个事务中,这样我就可以保持数据的一致性。在我的表格中我要求name
and email
.
既然我想要Invitation
在我看来,更改集可以正确地表示错误,我最终得到了这段代码......但看起来不太好。
你知道在 Phoenix + Ecto 中有更好的方法吗?
def create(params) do
Repo.transaction(fn ->
case Repo.insert(User.email_changeset(%User{}, params)) do
{:ok, user} ->
changeset = Invitation.changeset(%Invitation{}, params)
case Repo.insert(Ecto.Changeset.change(changeset, user_id: user.id)) do
{:ok, user} ->
user
{:error, changeset} ->
Repo.rollback(changeset)
end
{:error, _changeset} ->
Repo.rollback(%{Ecto.Changeset.add_error(changeset, :email, "Wrong email") | action: :insert})
end
end)
end
您正在寻找with
操作员。这种语法的美妙之处在于,如果在任何时候你没有得到你所期望的结果,它就会停止命令链并触发你的命令。else
block:
Repo.transaction(fn ->
with {:ok, first_object} <- create_some_object,
{:ok, second_object} <- create_another(first_object.something) do
second_object
else
{:error, error_key} ->
Repo.rollback(error_key)
end
end)
if create_some_object
不返回与 {:ok,first_object} 匹配的结构,则永远不会创建 secondary_object。很酷,对吧?
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)