ecto删除many_to_many连接,同时保持连接记录不变

时间:2019-03-05 19:36:48

标签: database elixir ecto elixir-framework

我有两个Ecto模型:UserSkill,它们通过many_to_many表与users_skills关联在一起:

create table(:users_skills, primary_key: false) do
  add :user_id, references(:users, on_delete: :nothing)
  add :skill_id, references(:skills, on_delete: :nothing)
end

create unique_index(:users_skills, [:user_id, :skill_id])

User模式中,有:

many_to_many :skills, Skill, join_through: "users_skills"

Skill模式中,有:

many_to_many :users, User, join_through: "users_skills"

我想做的是删除用户的技能,而不删除UserSkill本身。目前,我正在尝试:

query = Ecto.assoc(current_user, :skills)
Repo.delete_all(query)

但是它会引发错误:

(foreign_key_violation) update or delete on table "skills" violates foreign key constraint "users_skills_skill_id_fkey" on table "users_skills"

on_delete: :delete_all添加到users_skills迁移中时,具有删除相关技能的不良后果。

我该如何处理,以便仅删除关联记录,而UserSkill都保持原样?

1 个答案:

答案 0 :(得分:1)

我确信还有更好的方法,但是您可以在架构中将on_replace: :delete选项传递给many_to_many宏。

defmodule User do
  use Ecto.Schema

  schema "users" do
    field(:name)
    many_to_many(:skills, Skill, join_through: "users_skills", on_replace: :delete)

    timestamps()
  end
end

现在,如果您运行

current_user
|> Repo.preload(:skills)
|> Ecto.Changeset.change()
|> Ecto.Changeset.put_assoc(:skills, [])
|> Repo.update!()

它从users_skills表中删除,并且skills表将保持不变。