2009-08-27 13 views
65

Eventuali duplicati:
How can I avoid running ActiveRecord callbacks?Come saltare i callback di ActiveRecord?

ho modello come questo

class Vote < ActiveRecord::Base 
    after_save :add_points_to_user 

    ..... 
end 

E 'possibile forzare in qualche modo il modello di saltare chiamando add_points_to_user quando salvato? Forse qualcosa come ActiveRecord#delete vs ActiveRecord#destroy?

+0

A mio modesto parere, la domanda che si sostiene abbia già una risposta, ha solo risposte errate. Quindi non penso che questo si qualifichi come un duplicato. Penso che la risposta che fornisco qui sotto sia l'approccio ufficialmente autorizzato all'abbandono del callback. – sheldonh

risposta

29

Per Rails 2, ma non Rails 3 è possibile utilizzare questi:

object.send(:create_without_callbacks) 
object.send(:update_without_callbacks) 
+7

sfortunatamente questo non funziona più in Rails 3 :( –

+2

Vedere la mia risposta per un consiglio che copre Rails 2 e Rails 3. – sheldonh

+3

che 'Model' è fuorviante, quelli sono metodi di istanze AR, non classmethods, quindi' record.send (: create_without_callbacks) '. – tokland

151

Per Rails 3, ActiveSupport::Callbacks ti dà il controllo necessario. Stavo affrontando la stessa sfida in uno scenario di integrazione dei dati in cui i callback normalmente desiderabili dovevano essere ignorati. È possibile reset_callbacks in massa, o utilizzare skip_callback per disabilitare con giudizio, in questo modo:

Vote.skip_callback(:save, :after, :add_points_to_user) 

..dopo cui è possibile operare su casi votare con: add_points_to_user inibito

+37

Nel caso in cui non volessi liberarti definitivamente della callback, ma diciamo solo per una creazione/salvataggio quindi dovrà abilitarlo di nuovo dopo aver saltato i callback: 'User.set_callback: save,: after,: add_points_to_user' Notate anche che se ciò che fate tra le 2 chiamate potrebbe sollevare un'eccezione dovreste probabilmente avvolgerlo intorno start (-rescue) -ensure-block – Timo

+6

Esiste funzionalità simili per insi specifici tanza? – EyalB

+6

Quello che probabilmente suggerisco è, imposta 'skip_callback' in modo dichiarativo sulla classe con un'opzione': if' come 'if: lambda {@skip_callbacks == true}', e scrivi i metodi per racchiudere i casi in cui devi farlo : 'def some_special_operation !; @skip_callbacks = true; fare qualcosa; salvare!; @skip_callbacks = false; end' Potrebbe usare un metodo di gestione del contesto che imposta/disattiva l'ivar e restituisce un blocco, ma se hai bisogno di questo molto probabilmente c'è qualcosa che non va ;-) ** edit ** Ugh, odio SO commentare le restrizioni newline. – ches

41

si applica il testo seguente Rails 2, rotaie 3 e 4 binari:

http://guides.rubyonrails.org/v3.2.13/active_record_validations_callbacks.html#skipping-callbacks

esso fornisce un elenco dei metodi che saltano callback, che spiega perché è pericoloso usarli senza un'attenta considerazione. Ristampato qui sotto le disposizioni della licenza Creative Commons Attribution-Share Alike 3.0.

12 Skipping richiamate

Proprio come con convalide, è anche possibile saltare callback. Questi metodi devono essere utilizzati con cautela, tuttavia, poiché le importanti regole commerciali e la logica dell'applicazione possono essere mantenute nelle richiamate. Ignorandoli senza comprendere le potenziali implicazioni, è possibile che porti a dati non validi.

  • decremento
  • decrement_counter
  • eliminare
  • delete_all
  • find_by_sql
  • incremento
  • increment_counter
  • ginocchiera
  • tocco
  • update_column
  • update_all
  • update_counters
+0

Buono a sapersi! e funziona bene – Ben

+0

Come noto, in Rails 4.2, attiva solo l'oggetto modifica, ma non salvato nel database, è necessario richiamare il metodo di salvataggio dopo l'attivazione. se usi commutatore !, lo ha salvato in questo momento, ma attiverà la richiamata, quindi, dovrebbe essere rimosso da questo elenco. – zw963

+0

@ zw963 Ma attivare! non è nella lista, quindi non ha bisogno di essere rimosso. Stai dicendo che l'attivazione non-bang attiva anche i callback e quindi deve essere rimosso? La Guida dei binari sui richiami di ActiveRecord elenca ancora i metodi che saltano i callback in 4.2.1. – sheldonh

28

Ciò saltare i convalide:

vote.save(:validate => false) 
informazioni here

Per saltare i vostri callback e convalide più

, è possibile utilizzare, update_column v (3.1) o update_all

vote = Vote.first 
vote.update_column(:subject, 'CallBacks') 

Aparentlly questo funziona solo con ActiveRecord 3.1

Oppure:

Vote.where('id = ?', YourID).update_all(:subject => 'CallBacks') 

Alla fine si ha anche io finalmente opzione e questo salterà everthing:

execute "UPDATE votes SET subject = 'CallBacks' WHERE id = YourID" 

OK l'ultimo non è così carino.

+3

questo non salta i callback, solo le convalide – pduersteler

+0

update_all salta i callback da http://apidock.com/rails/ActiveRecord/Relation/update_all: "Non crea un'istanza dei modelli coinvolti e non attiva i callback di Active Record o convalide ". –

+2

update_column funziona anche se la sintassi sopra non è corretta. Si aspetta 2 parametri: vote.update_column (: subject, 'CallBacks') –