Ho un modello particolarmente complesso con convalide e callback definiti. Il business necessita ora di uno scenario particolare in cui aggiungere un nuovo record richiede di saltare le convalide e i callback. Qual'è il miglior modo per farlo?Rails 3 salta convalide e callback
risposta
Questo funziona in Rails 3:
Model.skip_callback(:create)
model.save(:validate => false)
Model.set_callback(:create)
Che sull'aggiunta di un metodo per il vostro modello che ti permette di saltare i callback?
class Foo < ActiveRecord::Base
after_save :do_stuff
def super_secret_create(attrs)
self.skip_callback(:create)
self.update_attributes(attrs)
self.save(:validate => false)
self.set_callback(:create)
end
end
Se si finisce per utilizzare qualcosa come questo, mi consiglia di utilizzare auto nel metodo al posto del nome del modello per evitare conascenza di nome.
Ho anche imbattuto in un succo di Sven Fuchs che sembra piacevole, è here
Mi piace questo approccio ma 'skip_callback' viene mostrato come un metodo di classe mentre 'update_attributes' è un metodo di istanza, è quello che intendevi? Hmm non capisco, il doc dell'API dice 'skip_callback' è un metodo di istanza ma non è così nella console di Rails, strano. –
Il mio introito era come questo (nota: questo disabilita callback su Crea, per aggiornare, cancellare e gli altri è necessario aggiungere loro di gamma).
begin
[:create, :save].each{|a| self.class.skip_callback(a) } # We disable callbacks on save and create
# create new record here without callbacks, tou can also disable validations with
# .save(:validate => false)
ensure
[:create, :save].each{|a| self.class.set_callback(a) } # and we ensure that callbacks are restored
end
In suvated, ma poi non ha funzionato per la mia app 3.2.6. Stavo chiamando Model.skip_callback (: create,: after) – TuteC
Questa è la soluzione per 3.0+ Non funzionerà su 2.x - ma ho ricordato che quando stavo cercando una soluzione a questo mi sono imbattuto in soluzione per 2 .x che non ha funzionato per 3.x –
Usa ActiveRecord::Persistence#update_column, in questo modo:
Model.update_column(field, value)
In base alla documentazione collegata: "I callback vengono richiamati." – eggie5
Penso che abbiate consultato la documentazione di 'update_attribute', non di' update_column'. Se si guarda la documentazione di 'update_column', è equivalente a' update_columns' per una singola colonna. I documenti per 'update_columns' indicano chiaramente che le convalide e le callback sono saltate. – bowsersenior
Salvami la vita! Ho provato skip_callback e altri metodi, senza fortuna. Funziona! –
Questo mod ha funzionato per me, finalmente (ridefinito _notify_comment_observer_for_after_create
metodo per l'oggetto):
if no_after_create_callback
def object._notify_comment_observer_for_after_create; nil; end
end
ho scritto un semplice gioiello per saltare convalide ad hoc, ma potrebbe probabilmente essere aggiornato per includere anche le richiamate saltate.
https://github.com/npearson72/validation_skipper
Si potrebbe prendere il can_skip_validation_for
nella gemma e aggiungere funzionalità per saltare anche le richiamate. Forse chiama il metodo can_skip_validation_and_callbacks_for
Tutto il resto funzionerebbe allo stesso modo. Se vuoi aiuto per farlo, fammi sapere.
Si consiglia di NON utilizzare l'approccio skip_callback poiché non è thread-safe. Il sneaky save gem tuttavia è poiché esegue semplicemente SQL. Nota che ciò non attiverà le convalide, quindi dovrai chiamarle tu stesso (es: my_model.valid?).
Ecco alcuni esempi dai loro documenti:
# Update. Returns true on success, false otherwise.
existing_record.sneaky_save
# Insert. Returns true on success, false otherwise.
Model.new.sneaky_save
# Raise exception on failure.
record.sneaky_save!
Se l'obiettivo è quello di inserire semplicemente o aggiornare un record senza callback o convalide, e si vorrebbe farlo senza ricorrere a gemme aggiuntive, aggiungendo condizionale controlla, usando RAW SQL, o futzing con il tuo codice in uscita in qualsiasi modo, può essere possibile utilizzare un "oggetto ombra" che punta alla tabella db esistente. In questo modo:
class ImportedUser < ActiveRecord::Base
# To import users with no validations or callbacks
self.table_name = 'users'
end
Questo funziona con tutte le versioni di Rails, è threadsafe, ed elimina completamente tutte le convalide e callback senza modifiche al codice esistente.Basta ricordarsi di utilizzare la nuova classe per inserire l'oggetto, come:
ImportedUser.new(person_attributes)
questo è così intelligente. mi hai salvato mal di testa! –
Nessuno di questi funzionerà se le vostre convalide sono scritti nel database stesso.
+------------------------------------+--------------------------------------------------+------+-----+--------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------------------------+--------------------------------------------------+------+-----+--------------------+----------------+
| status | enum('Big','Small','Ugly','Stupid','Apologetic') | NO | | Stupid | |
- 1. più convalide Rails 3 (Rails per Zombies; 2: 3)
- 2. Rails Specifica l'ordine delle convalide
- 3. my_object.save (false) non salta VERAMENTE le convalide di Active Record
- 4. Salta before_filter in Rails
- 5. Android Facebook LoginButton Callback salta all'annullato
- 6. Rails 3 e FCGI?
- 7. Rails 3 - Convalida personalizzata
- 8. Rails 3: Convalida valori combinati
- 9. Differenti tra salta e salta e collegamento
- 10. Rspec e callback 'before_validation' emette
- 11. Salta la migrazione del database durante la distribuzione dell'applicazione Rails utilizzando Capistrano 3
- 12. Converti vincoli di database in convalide di Rails
- 13. Rails 3.1, RSpec: convalida delle convalide del modello
- 14. Rails ActiveRecord - ottiene tutte le convalide da un modello
- 15. has_many: salvataggio automatico => true convalida salta quando si salvano i bambini
- 16. Utilizzo di Rails 3 e Haml 3, come configurare Haml?
- 17. Rails 3 e Strano Accetta intestazioni
- 18. Rails 3 metodi e API deprecati
- 19. Rails 3 - ActiveRecord e invertire sorta
- 20. Rails 3 e database di grafici
- 21. Gestione jsonp in rails 3 controller
- 22. Autentica utente dal server iOS Rails 3 e Omniauth
- 23. State Machine, Modello convalide e RSpec
- 24. Rails 3 Raccomandazione CMS
- 25. Rails 3 vs Sinatra
- 26. Rails 3: validazione form_tag
- 27. Rails 3 errori yaml
- 28. Rails 3 find_or_create_by
- 29. Rails 3: .build metodo
- 30. Rails 3 - set environment
Non hai ancora bisogno di usare '' 'set_callback (: create)' ''? Ho avuto l'impressione che '' 'skip_callback''' lo disabiliti fino a quando non viene riattivato. –
Penso di sì, non uso mai questo metodo, maggiori informazioni http://api.rubyonrails.org/classes/ActiveSupport/Callbacks/ClassMethods.html#method-i-skip_callback – Dinatih
Questo file non può essere protetto? sarebbe bello poterlo impostare su un livello di istanza .. –