2012-02-17 1 views
6

Ho provato molte cose per sovrascrivere il comportamento del metodo: destroy ma niente funziona. Ho usato prima il plugin acts_as_paranoia, ma non funziona con un modello in has_many: attraverso l'associazione.Rails: come sovrascrivere: metodo destroy?

voglio sovrascrivere: metodo destroy solo per fare qualcosa di simile:

def destroy 
    _run_destroy_callbacks { delete } 
    end 

    def delete  
    self.update_attribute(:status => 0) 
    freeze 
    end 

Cioè, voglio solo per aggiornare un altro campo (stato a 0) invece di distruggere il record stesso.

risposta

5

Hai provato ?:

class MyClass < ActiveRecord::Base 
    def destroy 
    update_attribute(:status, 0) 
    end 
end 

EDIT: Sulla base di commenti, ci potrebbe essere qualcos'altro al lavoro e potrebbe essere solo il (: dipendente => '') la designazione sulla definizione associazione - o se è un HABTM, potrebbe non funzionare affatto. Forse this info on delete and destroy through associations ti sarà d'aiuto? Sezione pertinente incollata di seguito:

Cancellare o distruggere?

has_many e has_and_belongs_to_many association hanno i metodi destroy, delete, destroy_all e delete_all.

Per has_and_belongs_to_many, delete e destroy sono gli stessi: essi causano la rimozione dei record nella tabella join.

Per has_many, destroy chiamerà sempre il metodo destroy dei record rimossi in modo da eseguire le richiamate. Comunque cancellerà lo o effettuerà la cancellazione in base alla strategia specificata dall'opzione : dipendente, oppure se no: l'opzione dipendente è data, allora sarà seguire la strategia predefinita. La strategia predefinita è: nullify (imposta le chiavi esterne su zero), ad eccezione di has_many: through, dove la strategia predefinita è delete_all (elimina i record di join, senza eseguire i loro callback ).

+0

Sì, è stata la prima cosa che ho provato. Questo non fa nulla. Posso vedere la richiesta DELETE FROM nei miei log. Il metodo di eliminazione personalizzata sembra non essere chiamato. –

+0

Hrm, in realtà lo uso in diversi modelli in diverse app e funziona senza problemi. C'è qualcosa di 'speciale' con questo particolare modello e stai chiamando cancellare o distruggere? Vorresti il ​​secondo. – miked

+0

Il record viene distrutto dal suo genitore in un AREL (relazione ActiveRecord), forse è il problema?In effetti, aggiorno il mio modello di vino e registro (forma principale, metodo di aggiornamento nel controller), e se scelgo di cancellare il bambino (il modello varietale che contiene la distruzione personalizzata), non viene chiamato apparentemente. Forse, il meccanismo delle rotaie è diverso da distruggere se è il genitore che distrugge il bambino (non chiamare distruggere sul modello figlio?) –

0

Come ha detto microfonato, questo codice è stata la buona se vogliamo distruggere il varietale "manualmente":

@varietal = Varietal.find('1')  
@varietal.destroy 

def destroy 
    update_attribute(:status, 0) 
end 

Questo funziona perfettamente. Tuttavia, come ho detto, se aggiorniamo il record genitore, non ho trovato il metodo destroy/delete/delete_all chiamato sul figlio ... Quindi se qualcuno ha un'idea ...

2

Penso che il migliore modo per farlo è quello di sovrascrivere il filtro before_destroy: per manipolare le persone a carico:

def Model 
    before_destroy: mark_as_deleted 

    def mark_as_deleted 
     self.update_attribute(:status => 0) 
    end 
end 

questo non sarebbe annullare la destroy però.

The full callback documentation is here.

+0

Questo chiama ancora destroy() nel controller, esegue solo prima il def. Restituire false non funziona, almeno non che potrei dire. –