2009-03-31 3 views
6

Ho un modello ActiveRecord con una colonna di stato. Quando il modello viene salvato con un cambio di stato, devo scrivere su un file di cronologia il cambio di stato e chi è stato responsabile della modifica. Stavo pensando che un callback after_save funzionerebbe alla grande, ma non posso usare lo status_changed? metodo dinamico per determinare che la scrittura della cronologia è necessaria per l'esecuzione. Non voglio scrivere nella cronologia se il modello è stato salvato ma lo stato non è stato modificato. Il mio unico pensiero su come gestirlo adesso è usare un flag di variabile di istanza per determinare se il after_save dovrebbe essere eseguito. Qualche idea?Rails after_save callback per creare un modello associato basato su column_changed?

risposta

0

Vedo due soluzioni:

  1. come hai detto tu: aggiungere una bandiera variabile ed eseguire richiamata quando viene impostato.

  2. Eseguire save_history dopo aver aggiornato il record.

Esempio:

old_status = @record.status 
if @record.update\_attributes(params[:record]) 
    save_history_here if old_status != @record.status 
    flash[:notice] = "Successful!" 
    ... 
else 
    ... 
end 
6

Utilizzare un callback before_save invece. Quindi hai accesso a entrambi i nuovi e vecchi valori di stato. Le callback sono racchiuse in una transazione, quindi se il salvataggio fallisce o viene annullato da un altro callback, verrà ripristinata anche la scrittura della cronologia.

10

questo potrebbe essere cambiato da quando la questione è stata inviata, ma il callback after_save dovrebbe avere i metodi dinamici *_changed? disponibili e impostare correttamente:

class Order 
    after_save :handle_status_changed, :if => :status_changed? 
end 

o

class Order 
    after_save :handle_status_changed 
    def handle_status_changed 
    return unless status_changed? 
    ... 
    end 
end 

funziona correttamente per me w/Rotaie 2.3.2.

-6

Qualcuno non ha mai sentito parlare di trigger di database? Se si scrive un trigger del database on_update sul server del database, ogni volta che viene aggiornato un record, verrà creata una copia cronologica dei valori del record precedente nella tabella di controllo associata.

Questa è una delle cose principali che disprezzo di Rails. Passa così tanto tempo a cercare di fare tutto per lo sviluppatore che ingannare gli sviluppatori nel pensare di dover seguire tali volgari corsi d'azione come scrivere metodi di guide specializzate per fare ciò che il malissimo server di database è già pienamente in grado di fare da solo.

scuote la testa in Rails, ancora una volta

+0

Se mi si può mostrare come fare una scrittura di database trigger per un file di log di storia, io upvote voi. – Georges

+0

Perché un trigger del database dovrebbe mai scrivere su un file di registro? L'unico scopo del trigger, in questo caso, funge da registro delle attività cronologiche sulla tabella per cui è stato scritto il trigger. La registrazione su un file è responsabilità di un'applicazione. Sto iniziando a pensare che c'è una fondamentale mancanza di comprensione di base del sistema. Ma stiamo parlando di Rails. Quindi, suppongo che questo spieghi la mentalità del "fai tutto senza sapere perché". Senza offesa, Georges. Ma Rails è una perversione della programmazione del buon senso al suo meglio. – Skittles

+0

Ah, mi dispiace. Immagino di aver originariamente interpretato erroneamente il tuo commento in quanto il commento originale menzionava un file * di cronologia *. Hai ragione. Una tabella di controllo e trigger è molto meglio in questo caso. Upvoted. – Georges