如何使表格和交易在phoenix + ecto中很好地发挥作用? [英] How to make forms and transactions play well in phoenix + ecto?

查看:66
本文介绍了如何使表格和交易在phoenix + ecto中很好地发挥作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在与Phoenix + Ecto玩,偶然发现了一些我觉得不习惯的东西.

I'm playing with Phoenix + Ecto and I stumbled upon something that does not feel idiomatic to me.

我有一个表示Invitation的表格.创建邀请时,我们还需要创建一个User,显然我希望两者都在事务中发生,以便保持数据一致性.在我的表单中,我要求输入nameemail.

I have a form that represents an Invitation. When creating an Invitation we also need to create a User and obviously I want both to happen in a transaction so I keep data consistency. In my form I ask for name and email.

因为我希望视图中的Invitation变更集能够正确表示错误,所以我最终获得了这段代码...但是看起来并不好.

Since I want the Invitation changeset in my view to represent the errors correctly I ended up with this code... but does not look great.

您知道在Phoenix + Ecto中执行此操作的更好方法吗?

Do you know a better way to do this in 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块:

You are looking for the with operator. The beauty of this syntax is that if, at any point, you don't get what you're expecting, it stops the chain of commands and fires your 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)

如果create_some_object没有返回与{:ok,first_object}匹配的结构,则永远不会创建second_object.太酷了吧?

if create_some_object doesn't return a struct matching {:ok, first_object} then the second_object is never created. Cool, right?

这篇关于如何使表格和交易在phoenix + ecto中很好地发挥作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆