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 更新与cast_assoc的关联_Elixir_Ecto - Fatal编程技术网

Elixir 更新与cast_assoc的关联

Elixir 更新与cast_assoc的关联,elixir,ecto,Elixir,Ecto,我有两个表用户和公司。用户属于一个公司,一个公司有很多用户 我有一个表单,可以将用户添加到公司中,该公司是作为嵌套表单实现的(inputs\u for),因此在公司的变更集中,我调用了cast\u assoc def changeset(company, attrs) do company |> cast(attrs, [:name, :email]) |> validate_required([:name, :email]) |> cast_a

我有两个表
用户
公司
。用户属于一个公司,一个公司有很多用户

我有一个表单,可以将用户添加到公司中,该公司是作为嵌套表单实现的(
inputs\u for
),因此在公司的变更集中,我调用了
cast\u assoc

def changeset(company, attrs) do
    company
    |> cast(attrs, [:name, :email])
    |> validate_required([:name, :email])
    |> cast_assoc(:users, with: &User.company_admin_changeset/2)
  end
我想做的是,当我向公司添加一个已经存在的用户时,它应该更新用户的公司id(外键)。如果用户不存在,只需创建一个

从我的需求来看,我开始认为从cast_assoc不可能做到这一点。因此,我使用了
transaction

  def create_company(attrs \\ %{}) do
    Repo.transaction(fn ->
      cmp =
        Company.changeset(%Company{}, %{name: attrs["name"], email: attrs["email"]})
        |> Repo.insert!()

      Enum.each(attrs["users"], fn {_, user} ->
        case Accounts.get_user_by_email(user["email"]) do
          nil ->
            User.company_admin_changeset(%User{}, %{email: user["email"], company_id: cmp.id})
            |> Repo.insert!()

          account ->
            account |> Ecto.Changeset.change(company_id: cmp.id) |> Repo.update!()
        end
      end)
    end)
  end

但是如果可能的话,你能告诉我怎么做吗?

我使用了upserts,但我必须根据用户是否存在来运行自定义方法,所以我仍然使用我的旧代码处理事务

我认为你的方法是正确的——你的用例似乎不属于协会的
:on\u replace
选项但是,您可以稍微清理一下您的流程,以利用
exto.Repo.get\u by/3
exto.Repo.insert\u或\u update/2