Экто удалить указанную запись базы данных

У меня 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.ConstraintError при попытке удалить запись «Пользователь» (я предполагаю, потому что с этим пользователем связана запись «Другой»)

Итак, как бы мне заставить его работать так, как я хочу:

  • "Пользователь" может быть создан автономно
  • «Другой» может быть создан, но он должен принадлежать «пользователю»
  • Удаление «другого» не влияет ни на что другое.
  • Когда "пользователь" удаляется, он также удаляет все связанные "другие" записи.

По сути, каскадное удаление для пользователя любых элементов, которые на него ссылаются.


person TheStoneFox    schedule 09.01.2016    source источник


Ответы (2)


Вы можете сделать это так, как вы указали в своей схеме, используя:

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 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
person Gazler    schedule 09.01.2016
comment
Решение для существующего индекса, похоже, пока не работает (июнь 2018 г.). Вот это решение работает: stackoverflow.com/a/45770507/1460448 - person xji; 12.06.2018

Я понял это, на многих вы можете передать параметр on_delete

поэтому has_many выглядит так

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

Документы очень полезны: p

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

person TheStoneFox    schedule 09.01.2016