2016-01-09 14 views
14

Ho 2 tabelle:Ecto delete riferimento record del database

utente:

id 
username 
password 

unique_index username 

(the schema has a has_many other) 

altro:

id 
user_id - references(:users) 
foo 

index user_id 

(the schema has a belongs_to user) 

nel changeset per "Other" Ho questo

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

La mia ipotesi, a questo punto è stata la "Altro" modello Ecto richiede un "utente" da associare ad essa di esistere (che è quello che voglio)

Ma la mia seconda ipotesi era se si elimina l ' "Utente" record quindi tutti i record "Altro" associati verrebbero eliminati (tramite eliminazione Cascade)

Che cosa succede in realtà è che ho un Ecto.ConstraintError quando provo a eliminare un record "Utente" (presumo perché c'è un " Altro "record associato a quell'utente)

Quindi, come potrei farlo funzionare nel modo in cui desidero:

  • A "utente" può essere creata standalone
  • un "altro" può essere creato, ma deve appartenere a un "utente"
  • Quando un "altro" è cancellato non interessa niente altro
  • Quando un "utente" è soppressa ed elimina tutte le associate "altre" record anche

Essenzialmente un'eliminazione a cascata sulla utente per tutti gli elementi che vi fa riferimento

risposta

34

si può fare il modo in cui è stato specificato sul vostro schema utilizzando:

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

Tuttavia, si può essere scommessa ter fare questo in migrazione con references/2:

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

Questo utilizza il database di vincoli di chiave esterna ed è menzionato nei has_many documentazione:

: on_delete - L'azione intrapresa sulle associazioni quando modello di genitore sono soppressi . Può essere: nothing (predefinito),: nilify_all e: delete_all. Avviso: on_delete può anche essere impostato nelle migrazioni durante la creazione di un riferimento.Se supportato, basandosi sul database tramite le migrazioni è preferito

È possibile modificare un indice esistente con:

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