2014-06-11 13 views
9

Diciamo che ho tre modelli Active Record:Rails polimorfa dipendente:: distruggere non funziona correttamente

class Tissue 
    has_many :boogers, as: :boogerable, dependent: :destroy 
end 

class Finger 
    has_many :boogers, as: :boogerable, dependent: :destroy 
end 

Class Boogers 
    belongs_to :boogerable, polymorphic: true 
end 

Diciamo che la mia domanda può trasferire una caccola da un dito ad un tessuto, e una volta fatto questo, il dito è distrutto (yikes!). Per qualche ragione, quando il dito viene distrutto, sta anche distruggendo i boogers che precedentemente appartenevano ad esso e da allora sono stati trasferiti su un tessuto. Nel registro posso vedere che quando il dito viene distrutto ricorda l'ID dei boogers che USED ne fa parte e li distrugge. Non controlla se il boogerable_type è ancora 'finger' e quindi distrugge quelli con tipo 'tissue'.

Quando un dito viene distrutta, si sta facendo questo:

DELETE FROM boogers WHERE booger.id = 387 

Quando si dovrebbe fare questo:

DELETE FROM boogers WHERE boogerable_id = 1 AND boogerable_type = 'finger' 

Chiunque venire attraverso questo prima?

+0

Mostraci il codice in cui stai trasferendo e distruggendo. –

+0

la tua domanda è utile, funziona per me. –

risposta

6

Innanzitutto, è necessario sapere che il metodo ActiveRecord destroy utilizza il campo dell'oggetto :id quando è necessario distruggerlo. E che l'opzione dependent: :destroy attiverà il metodo destroy su tutti gli oggetti assegnati con l'oggetto corrente.

Presumo che si sta facendo qualcosa di simile:

f = Finger.find(finger_id) 
t = Tissue.find(tissue_id) 

f.boogers[0].boogerable = t 
f.boogers[0].save! 

f.destroy 

La dichiarazione dependent: :destroy significa che quando destroy è chiamato f, sarà inoltre chiamata a deliberare tutte le caccole che sono associati con f. E dal momento che f e i suoi booger sono caricati in memoria, l'oggetto f.booger[0] esiste ancora nella matrice di f.boogers che avrà ciascuno dei suoi elementi, tra cui boogers[0], distrutto quando f viene distrutto.

La soluzione di questo caso è che si preme f.boogers.reload per aggiornare l'array prima del chiamando f.destroy.

Inoltre, si ricorda che quando si distrugge f, tutto associato boogers sarà destroy ed oltre, è davvero questo che vuoi? distruggi il dito con tutti gli altri boogers associati quando uno di questi viene trasferito su qualcos'altro?

+3

L'aggiornamento dell'array con la ricarica è stata la soluzione! Grazie mille. Punti extra per rispondere con una faccia seria. –