5

The Rails 4 documentazione dice questo riguardo distruggere le richiamate sul modello unirsi per un rapporto has_many :through:Perché la raccolta non = oggetti su has_many: tramite richiami di attivazione sul modello di join alla cancellazione dell'associazione?

collection=objects sostituisce le collezioni di contenuti eliminando e l'aggiunta di oggetti a seconda dei casi. Se l'opzione: through è true, i callback nei formati join vengono attivati, ad eccezione dei callback, poiché la cancellazione è diretta.

Per fortuna è documentato almeno, ma voglio sapere perché diamine è così? Spero che ci sia un motivo tecnico perché altrimenti è solo pazzesco!

Nel mio caso ho avuto una relazione has_and_belongs_to_many sul modello di tabelle join su un altro modello. I record su quella seconda tabella di join non verranno mai eliminati quando i record associati sulla prima tabella di join sono stati eliminati. Ho fatto ricorso a questo che si sente hacky, e devo ripetermi su ogni lato della :through rapporto:

has_many :schools_templates, dependent: :destroy 
has_many :templates, through: :schools_templates, before_remove: :remove_groups_school_templates 

private 

def remove_groups_school_templates(template) 
    schools_templates.where(template: template).first.groups.clear 
end 

C'è una convalida per 'garantire' unicità sul unire le tabelle record tra le due chiavi esterne, in modo che perché posso chiamare first nella richiamata.

risposta

0

Quindi mi sono imbattuto nello stesso problema l'altro giorno. Nel mio caso stavo facendo qualcosa di simile a quello che stavi facendo e stavo incontrando lo stesso problema con la tabella di join eliminata invece di essere distrutta.

Ho iniziato a consultare il codice e credo che la documentazione sia appena scaduta. has_many_through_association

Tutto ciò che devi fare è aggiungere il dipendente:: destroy alla relazione has_many: through.

class User 
    has_many :partnerships, dependent: :destroy 
    has_many :partners, through: :partnerships, dependent: :destroy 
end 

Il dolore avevo a che fare con era:

user.partner_ids = [1,2,3] 
#creates the relationships 
user.partner_ids = [] 
#was deleting the records from partnerships without callbacks. 

Il dipendente:: distruggere sul rapporto partner fissa che. I callback ora vengono eseguiti e le cose vanno di nuovo bene.

2

genere se si desidera eliminare qualcosa attraverso has_many associazione mettere dependent: :destroy lì:

class User 
    has_many :partnerships, dependent: :destroy 
    has_many :partners, through: :partnerships 
end 

Se si vuole distruggere partners così come collaborazioni si deve aggiungere questa dipendenza per Partnership s modello:

class Partnership 
    belongs_to :partner, dependent: :destroy 
    belongs_to :user 
end 

Quando l'oggetto viene distrutto, chiama destroy su ogni oggetto in cui viene fornita la dipendenza di destroy. Quindi le chiamate User vengono eliminate su ogni Partnership e tutte le chiamate Partnership vengono eliminate su ogni Partner.

"Perché non può essere utilizzato con through" - beh, la risposta è "poiché la cancellazione è diretta". So che non dice molto (anche per me), ma d'altra parte per me aggiungere dipendenze a oggetti che non sono collegati direttamente è una cattiva idea. Considera l'esempio sopra: se dipendente - destroy funzionerà sui partner e li distruggerà - dovrebbe distruggere anche il modello di join? Sicuramente sì, perché in altri casi porterà alla corruzione dei dati, ma potresti perdere alcuni dati che potrebbero trovarsi nel modello di join, quindi in alcuni casi, no, non vuoi distruggere il modello di join. Ciò significa che il team di Rails dovrebbe aggiungere un nuovo parametro - delete_join per indicare se si desidera salvare quel modello o meno. E questo è solo un pessimo design, dal momento che abbiamo già un approccio migliore - aggiungere dipendenze nei modelli di join.

+0

Grazie per la risposta :) Ho aggiornato la domanda per dimostrare che avevo già impostato il set di distruzione dipendente sull'associazione con il modello di join. Non sono sicuro del motivo per cui ho perso quella :) Suppongo che la mia tesi sia che la cancellazione non dovrebbe essere "diretta", dovrebbe innescare callback "destroy" sul modello di join. –

Problemi correlati