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