【问题标题】:Ecto delete referenced database recordEcto 删除引用的数据库记录
【发布时间】:2016-01-09 08:04:43
【问题描述】:

我有 2 张桌子:

用户:

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(我假设是因为有与该用户关联的“其他”记录)

那么我将如何让它以我想要的方式工作:

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

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

【问题讨论】:

    标签: elixir ecto


    【解决方案1】:

    您可以按照您在架构上指定的方式使用:

    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 文档中提到:

    :on_delete - 删除父模型时对关联采取的操作。可能是 :nothing (默认)、: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
    

    【讨论】:

    【解决方案2】:

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

    所以 has_many 看起来像这样

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

    文档非常有用:p

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-04
      • 2019-06-03
      • 2014-06-11
      • 2014-11-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多