问题描述
我有两个表 Users
和 Companies
。用户属于一个公司,一个公司有很多用户。
我有一个表单,我可以在其中将用户添加到以嵌套表单 (inputs_for
) 实现的公司中,因此在公司的变更集中,我调用了 cast_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
我想要做的是,当我将已经存在的用户添加到公司时,它应该更新用户的 company_id(foreign_key)。如果用户不存在,就创建一个。
看看我的要求,我开始认为从 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,但我必须根据用户是否存在来运行自定义方法,所以我仍然使用我的旧代码进行事务