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)
Мое предположение в этот момент было "Другой" ecto-моделью требует, чтобы "Пользователь" был связан с ним, чтобы существовать (это то, что я хочу)
Но мое второе предположение заключалось в том, что если я удалю запись "Пользователь", все связанные с ней записи "Другие" будут удалены (с помощью Cascade delete)
Что на самом деле происходит, у меня есть Ecto.ConstraintError при попытке удалить запись "Пользователь" (я предполагаю, потому что есть "Другая" запись, связанная с этим пользователем)
Итак, как бы я начал работать так, как хочу:
- "Пользователь" может быть создан автономно
- "Другой" может быть создан, но должен принадлежать "пользователю"
- Когда удаляется "другое", это ничего не влияет на
-
- Когда "пользователь" удален, он также удаляет все связанные с ним "другие" записи
По существу Cascade Delete для пользователя для любых элементов, которые ссылаются на него
Ответы
Ответ 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 - действие, выполняемое ассоциациями при удалении родительской модели. Может быть: ничего (по умолчанию),: 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