Ecto は参照されたデータベースレコードを削除します 質問する

Ecto は参照されたデータベースレコードを削除します 質問する

テーブルが 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)

この時点での私の想定は、「その他」のエクトモデルが存在するためには「ユーザー」が関連付けられている必要があるというものでした(これが私の希望です)。

しかし、私の2番目の仮定は、「ユーザー」レコードを削除すると、関連するすべての「その他」レコードも削除されるというものでした(カスケード削除経由)。

実際に起こるのは、「ユーザー」レコードを削除しようとすると Ecto.ConstraintError が発生することです (そのユーザーに関連付けられた「その他」レコードがあるためだと思います)

では、私が望む通りに動作させるにはどうしたらよいでしょうか。

  • 「ユーザー」はスタンドアロンで作成できます
  • 「その他」は作成できますが、「ユーザー」に属している必要があります
  • 「その他」を削除しても、他のものには影響しません
  • 「ユーザー」が削除されると、関連する「その他」のレコードもすべて削除されます。

基本的に、それを参照するすべてのアイテムに対してユーザーに対するカスケード削除を実行します。

ベストアンサー1

次のようにして、スキーマで指定した方法で実行できます。

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

ただし、移行時にこれを行う方が良いかもしれません。参考文献/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

おすすめ記事