Rotaie: dipendente =>: distruggere VS: dipendente =>: delete_all


192

Nelle guide di binari è descritto in questo modo:

Gli oggetti verranno inoltre distrutti se associati :dependent => :destroye cancellati se associati:dependent => :delete_all

Bene, fico. Ma qual è la differenza tra essere distrutti ed essere cancellati? Ho provato entrambi e sembra fare la stessa cosa.

Risposte:


200

La differenza è con il callback.

La :delete_allè fatta direttamente nella vostra applicazione e cancella da SQL:

DELETE * FROM users where compagny_id = XXXX

Con il :destroy, c'è un'istanza di tutti i tuoi figli. Quindi, se non riesci a distruggerlo o se ognuno ha il suo :dependent, i suoi callback possono essere chiamati.


83
L'istanza e la chiamata a distruggere su ciascuno degli oggetti figlio sarà lenta se hai molti figli (e n ^ 2 se hai nipoti, e così via). delete_all è il tipo di soluzione "Nuke it from orbit" in cui non ti interessa / non hai alcun callback prima / dopo sui modelli.
Ryan Bigg,

131

Su un'associazione di modelli di Rails è possibile specificare l' :dependentopzione, che può assumere una delle tre forme seguenti:

  • :destroy/:destroy_allGli oggetti associati vengono distrutti accanto a questo oggetto chiamando il loro destroymetodo
  • :delete/:delete_allTutti gli oggetti associati vengono immediatamente distrutti senza chiamare il loro :destroymetodo
  • :nullifyLe chiavi esterne di tutti gli oggetti associati sono impostate su NULLsenza chiamare i loro savecallback

2
Vedi api.rubyonrails.org/classes/ActiveRecord/Associations/… (cerca "annulla") per l'autorevole rdocs.
sig.

21
Da Rails 3.0 è anche possibile specificare :restrict. Se impostato su: limita questo oggetto non può essere cancellato se ha qualche oggetto associato.
RocketR,

17
non ci sono :deleteo :destroy_allopzioni dal suo aspetto? L'opzione: dipendente si aspetta che: destroy,: delete_all,: nullify o: limits (: delete)
Mike Campbell,

2
@MikeCampbell :deletee le :destroy_allopzioni non esistono. Tuttavia, ci sono metodi di classe sui modelli chiamati deletee destroy_allquindi potrebbe essere il motivo della confusione.
berezovskyi,

@MikeCampbell Manca qualche altra opzione, vedi L'opzione: dipendente deve essere una delle [: destroy,: delete_all,: nullify,: restrizioni_with_error,: restrizioni_with_exception]
Pravin Mishra

30

Vedi distrugge elimina i suoi elementi associati in cui delete_all può eliminare più dati da self table comeDELETE * FROM table where field = 'xyz'

: Opzioni possibili dipendenti:

Controlla cosa succede agli oggetti associati quando il loro proprietario viene distrutto. Si noti che questi sono implementati come callback e Rails esegue i callback in ordine. Pertanto, altri callback simili possono influire sul comportamento dipendente e il :dependentcomportamento potrebbe influire su altri callback.

:destroy fa sì che anche tutti gli oggetti associati vengano distrutti.

:delete_all fa sì che tutti gli oggetti associati vengano eliminati direttamente dal database (quindi i callback non verranno eseguiti).

:nullifyfa sì che le chiavi esterne siano impostate su NULL. I callback non vengono eseguiti.

:restrict_with_exception genera un'eccezione se sono presenti record associati.

:restrict_with_error provoca un errore da aggiungere al proprietario se ci sono oggetti associati.

Se si utilizza con l' :throughopzione, l'associazione sul modello di join deve essere appartiene a e i record che vengono eliminati sono i record di join, anziché i record associati.


3

In realtà la differenza principale è che eventuali callback non verranno invocati quando è :delete_allstato utilizzato. Ma quando viene utilizzato :destroylo stack di callback ( :after_destroy, :after_commit...) verrà attivato.

Di conseguenza, se hai delle touch:dichiarazioni ing nei modelli che vengono eliminati, allora è meglio usare dependent: :delete_allpiuttosto 'dipendente:: distruggere'.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.