Ecto删除引用的数据库记录

时间:2016-01-09 08:04:43

标签: elixir ecto

我有两张桌子:

用户:

id
username
password

unique_index username

(the schema has a has_many other)

其他

id
user_id - references(:users)
foo

index user_id

(the schema has a belongs_to user)

在“其他”的变更集中我有这个

model
|> cast(params, @req, @opt)
|> foreign_key_constraint(:user_id)

我在这一点上的假设是“其他”ecto模型需要“用户”与它相关联才能存在(这就是我想要的)

但我的第二个假设是,如果删除“用户”记录,则会删除所有关联的“其他”记录(通过级联删除)

实际发生的是我在尝试删除“用户”记录时有一个Ecto.ConstraintError(我假设因为有一个与该用户关联的“其他”记录)

那么我将如何以我想要的方式工作呢?

  • 可以独立创建“用户”
  • 可以创建“其他”,但必须属于“用户”
  • 当删除“其他”时,它不会影响任何其他内容
  • 删除“用户”时,它也会删除所有关联的“其他”记录

对于任何引用它的项目,基本上是用户级联删除

2 个答案:

答案 0 :(得分:48)

您可以使用以下方式在架构上指定的方式执行:

has_many :other, Project.Other, on_delete: :delete_all

但是,在使用references/2进行迁移时,您可能会做得更好:

create table(:others) do
  add :user_id, references(:users, on_delete: :delete_all)
end

这将使用数据库外键约束,并在has_many docs中提及:

  

:on_delete - 删除父模型时对关联采取的操作。可能是:没有(默认),:nilify_all和:delete_all。注意:创建引用时,也可以在迁移中设置on_delete。如果支持,则优先通过迁移依赖数据库

您可以使用以下内容更改现有索引:

drop_if_exists index(:others, [:user_id])
alter table(:others) do
  modify :user_id, references(:users, type: :uuid, on_delete: :delete_all)
end

答案 1 :(得分:7)

我想通了,有很多你可以通过on_delete选项

所以has_many看起来像这样

has_many :other, Project.Other, on_delete: :delete_all

文档非常有帮助:p

https://hexdocs.pm/ecto/Ecto.Schema.html#has_many/3