Ho un osservatore e registro un callback after_commit
. Come posso sapere se è stato attivato dopo la creazione o l'aggiornamento? Posso dire che un articolo è stato distrutto chiedendo item.destroyed?
ma #new_record?
non funziona poiché l'elemento è stato salvato.Rails 3: Come identificare l'azione after_commit negli osservatori? (crea/aggiorna/distruggi)
stavo per risolverlo aggiungendo after_create
/after_update
e fare qualcosa di simile @action = :create
all'interno e controllare il @action
a after_commit
, ma sembra che l'istanza osservatore è un Singleton e potrei ignorare un valore prima che arrivi al after_commit
. Così l'ho risolto in modo più brutto, memorizzando l'azione in una mappa basata su item.id su after_create/update e controllandone il valore su after_commit. Davvero brutto.
C'è qualche altro modo?
Aggiornamento
Come @tardate detto, transaction_include_action?
è una buona indicazione, anche se è un metodo privato, e in un osservatore dovrebbe essere letta con #send
.
class ProductScoreObserver < ActiveRecord::Observer
observe :product
def after_commit(product)
if product.send(:transaction_include_action?, :destroy)
...
Purtroppo, l'opzione :on
non funziona in osservatori.
Assicurati di testare l'inferno dei tuoi osservatori (cerca test_after_commit
gem se usi use_transactional_fixtures) così quando esegui l'aggiornamento alla nuova versione di Rails saprai se funziona ancora.
(testato su 3.2.9)
Update 2
al posto degli osservatori io uso ActiveSupport :: Preoccupazione e after_commit :blah, on: :create
vi lavora.
Stai cercando di sapere se il tuo record era nuovo o no quando il after_commit è stato attivato? Leggendo la tua domanda e le risposte, trovo che sia confusa. Potresti riformulare la frase o fornirci un chiaro esempio? – charlysisto
La soluzione iniziale funziona se si utilizza un server a thread singolo. Se non lo stai utilizzando, passa a uno, ad esempio unicorno, per risolvere questo problema in modo pulito. Rende il modello di programmazione molto più semplice, avrai meno mal di testa (come questo) e alla fine sarà più veloce. L'uso di + transaction_include_action? + Non è pulito, in quanto si tratta di un metodo di guide protetto non supportato non supportato da alcun test nella suite di test delle rotaie. La prossima versione potrebbe non avere quel metodo. –
@elado Sono confuso. La risposta accettata (tardate) non funziona con gli osservatori (come notato dal commento di Ches). Hai deciso di utilizzare invece i callback? Per favore aggiungi una spiegazione alla tua domanda. – Kelvin