Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Elixir 如何使表单和交易在凤凰城发挥良好作用+;外星人?_Elixir_Phoenix Framework_Ecto - Fatal编程技术网

Elixir 如何使表单和交易在凤凰城发挥良好作用+;外星人?

Elixir 如何使表单和交易在凤凰城发挥良好作用+;外星人?,elixir,phoenix-framework,ecto,Elixir,Phoenix Framework,Ecto,我正在玩Phoenix+Ecto,我偶然发现了一些我觉得不习惯的东西 我有一个表示邀请的表单。在创建邀请时,我们还需要创建一个用户,显然我希望这两种情况都发生在一个事务中,以便保持数据的一致性。在我的表格中,我要求姓名和电子邮件 由于我希望视图中的邀请变更集能够正确表示错误,因此我最终得到了以下代码。。。但是看起来不太好 你知道一个更好的方法在凤凰+星上做到这一点吗 def创建(参数)do 回购交易(fn-> case Repo.insert(User.email_changeset(%User

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

我有一个表示邀请的表单。在创建邀请时,我们还需要创建一个
用户
,显然我希望这两种情况都发生在一个事务中,以便保持数据的一致性。在我的表格中,我要求
姓名
电子邮件

由于我希望视图中的
邀请
变更集能够正确表示错误,因此我最终得到了以下代码。。。但是看起来不太好

你知道一个更好的方法在凤凰+星上做到这一点吗

def创建(参数)do
回购交易(fn->
case Repo.insert(User.email_changeset(%User{},params))do
{:好的,用户}->
变更集=邀请。变更集(%Invitation{},params)
案例报告插入(外部变更集变更(变更集,用户\u id:user.id))do
{:好的,用户}->
用户
{:错误,变更集}->
回购回滚(变更集)
结束
{:错误,_changeset}->
Repo.rollback(%%{exto.Changeset.add_error(Changeset,:email,“错误的email”)| action::insert})
结束
(完)
结束

您可以尝试使用
exto.Multi
。以下是一个示例:

defmodule Service do
  alias Ecto.Multi
  import Ecto

  def insert_changeset(params) do
    Multi.new
    |> Multi.insert(:user, User.email_changeset(%User{}, params))
    |> Multi.insert(:invitation, Invitation.changeset(%Invitation{}, params))
  end
end
以及您的创建功能:

def create(params) do
  Service.insert_changeset(params)
  |> Repo.transaction
end
或者,您可以通过模式匹配使代码更漂亮

  def create(params) do
    Repo.transaction(fn ->
      changeset = User.email_changeset(%User{}, params)
      changeset
      |> Repo.insert
      |> invitation_insert(params)
    end)
  end

  defp invitation_insert({:error, changeset}, _params), do: Repo.rollback(changeset)
  defp invitation_insert({:ok, _}, params) do
    Invitation.changeset(%Invitation{}, params)
    |> Repo.insert
    |> do_invitation_insert
  end

  defp do_invitation_insert({:ok, user}), do: user
  defp do_invitation_insert({:error, changeset}), do: Repo.rollback(changeset)

您正在使用运算符查找
。这种语法的妙处在于,如果在任何时候,您没有得到预期的结果,它会停止命令链并触发
else
块:

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)
回购交易(fn->
使用{:ok,first_object}时,我想使用
Multi
,但在我的例子中,我需要首先创建
user
,因为我需要
user\u id
作为我的邀请。看起来
Multi
是用于“并行”操作的。模式匹配版本看起来确实更好!是否
defp做邀请插入({:error,changeset}),do:Repo.rollback(changeset)
也回滚
User
?@Omin是的,它仍然在同一事务中。但是,如何将错误从EXTO.Multi返回到表单?