2016-01-09 10 views
14

Mam 2 tabele:Ecto delete odwołuje rekord bazy

użytkownik:

id 
username 
password 

unique_index username 

(the schema has a has_many other) 

inne:

id 
user_id - references(:users) 
foo 

index user_id 

(the schema has a belongs_to user) 

w changeset dla "Inne" Mam ten

model 
|> cast(params, @req, @opt) 
|> foreign_key_constraint(:user_id) 

Moje założenie w tym miejscu był „Inny” Model ekto wymaga „Użytkownik”, aby być z nim związane istnieć (czego chcę)

Ale mój drugi założenie było gdybym usunąć „user” wtedy wszystkie powiązane "inne" rekordy zostaną usunięte (przez kasowanie)

Co się dzieje, to mam Ecto.ConstraintError podczas próby usunięcia rekordu "User" (zakładam, ponieważ istnieje " Inne "zapisy związane z tym użytkownikiem)

W jaki sposób chciałbym, aby działało tak, jak chcę, czyli:

  • A „użytkownik” może być utworzona samodzielna
  • „inny” może być utworzona, ale musi należeć do „użytkownik”
  • Gdy „inne” są usuwane nie wpływa to nic innego
  • Kiedy „użytkownik” jest usuwany usuwa wszystkie związane z „innymi” rekordy zbyt

Zasadniczo Cascade Delete użytkownika za jakiekolwiek przedmioty, które Referencje to

Odpowiedz

34

Można zrobić to w sposób podanej na schemat za pomocą:

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

Możesz być jednak pewien ter robi to w migracji z references/2:

create table(:others) do 
    add :user_id, references(:users, on_delete: :delete_all) 
end 

To będzie wykorzystywać bazy danych kluczy obcych i jest wymieniony w has_many docs:

: on_delete - Działania podjęte na skojarzeniach gdy modelu rodzic usuniętych . Może być: nic (domyślnie),: nilify_all i: delete_all. Uwaga: on_delete można również ustawić w migracji podczas tworzenia odniesienia.Jeśli obsługiwana, opierając się na danych poprzez migracje jest preferowana

Można zmienić istniejący indeks z:

drop_if_exists index(:others, [:user_id]) 
alter table(:others) do 
    modify :user_id, references(:users, type: :uuid, on_delete: :delete_all) 
end