phoenix ecto 删除关系
phoenix ecto relationships on delete
有两种模型:资源和元数据:
defmodule Myapp.Repo.Migrations.CreateResources do
use Ecto.Migration
def change do
create table(:resources) do
add :name, :string
add :parent_id, references(:resources, on_delete: :delete_all)
timestamps
end
create index(:resources, [:parent_id])
end
end
defmodule Myapp.Repo.Migrations.CreateMetadata do
use Ecto.Migration
def change do
create table(:metadata) do
add :size, :integer
add :resource_id, references(:resources)
timestamps
end
create index(:metadata, [:resource_id])
end
end
schema "resources" do
field :name, :string
belongs_to :parent, Myapp.Resource
has_one :metadata, Myapp.Metadata, on_delete: :delete_all
has_many :childs, Myapp.Resource, foreign_key: :parent_id, on_delete: :delete_all
timestamps()
end
schema "metadata" do
field :size, :integer
belongs_to :resource, Myapp.Resource
timestamps()
end
资源可以有 children,其中 parent_id = id。
还有一个资源元数据。 Table 元数据有 resource_id 列。
现在,我想通过删除所有他的 children 和所有关联的元数据来删除资源。
当我写
Repo.delete resource
我收到一个错误:
[error] #PID<0.441.0> running Myapp.Endpoint terminated
Server: localhost:4000 (http)
Request: POST /resources/%2Fdocs%2Ftest
** (exit) an exception was raised:
** (Postgrex.Error) ERROR (foreign_key_violation): update or delete on table "resources" violates foreign key constraint "metadata_resource_id_fkey" on table "metadata"
table: metadata
constraint: metadata_resource_id_fkey
Key (id)=(3) is still referenced from table "metadata".
仅在触发从资源中删除元数据时出现 children。如果我尝试删除没有 children 的资源,则一切正常。
显然,删除children 所需的回调不会导致删除元数据,因此 Postgres 出错。
是否可以解决此问题而不会受到 resource_id 元数据 metadata_id 资源的影响,并且不会开始递归手动删除所有 children 资源?
:delete_all 不会级联到子记录,除非通过数据库迁移设置。要解决此问题,请确保将元数据迁移脚本行更改为
add :resource_id, references(:resources, on_delete: :delete_all)
有两种模型:资源和元数据:
defmodule Myapp.Repo.Migrations.CreateResources do
use Ecto.Migration
def change do
create table(:resources) do
add :name, :string
add :parent_id, references(:resources, on_delete: :delete_all)
timestamps
end
create index(:resources, [:parent_id])
end
end
defmodule Myapp.Repo.Migrations.CreateMetadata do
use Ecto.Migration
def change do
create table(:metadata) do
add :size, :integer
add :resource_id, references(:resources)
timestamps
end
create index(:metadata, [:resource_id])
end
end
schema "resources" do
field :name, :string
belongs_to :parent, Myapp.Resource
has_one :metadata, Myapp.Metadata, on_delete: :delete_all
has_many :childs, Myapp.Resource, foreign_key: :parent_id, on_delete: :delete_all
timestamps()
end
schema "metadata" do
field :size, :integer
belongs_to :resource, Myapp.Resource
timestamps()
end
资源可以有 children,其中 parent_id = id。 还有一个资源元数据。 Table 元数据有 resource_id 列。 现在,我想通过删除所有他的 children 和所有关联的元数据来删除资源。 当我写
Repo.delete resource
我收到一个错误:
[error] #PID<0.441.0> running Myapp.Endpoint terminated
Server: localhost:4000 (http)
Request: POST /resources/%2Fdocs%2Ftest
** (exit) an exception was raised:
** (Postgrex.Error) ERROR (foreign_key_violation): update or delete on table "resources" violates foreign key constraint "metadata_resource_id_fkey" on table "metadata"
table: metadata
constraint: metadata_resource_id_fkey
Key (id)=(3) is still referenced from table "metadata".
仅在触发从资源中删除元数据时出现 children。如果我尝试删除没有 children 的资源,则一切正常。
显然,删除children 所需的回调不会导致删除元数据,因此 Postgres 出错。
是否可以解决此问题而不会受到 resource_id 元数据 metadata_id 资源的影响,并且不会开始递归手动删除所有 children 资源?
:delete_all 不会级联到子记录,除非通过数据库迁移设置。要解决此问题,请确保将元数据迁移脚本行更改为
add :resource_id, references(:resources, on_delete: :delete_all)