2012-01-25 14 views
15

Ho riscontrato un problema con gli errori di convalida durante il salvataggio di un modello mediante salvataggio !. I messaggi di errore del modello di errore ActiveRecord sono vuoti, quindi non so quali errori si verificano in un tentativo di convalida. Quando provo errors.full_messages o errors.each_full in base allo documentation, dovrebbe visualizzare gli errori, che non è così.Rails che ottiene errore di convalida non riuscito, ma nessun errore nel modello di errore ActiveRecord

Il modello che sto cercando di salvare è il modello Ordini (sito di e-commerce che utilizza Spree). Quando un elemento nell'ordine viene eliminato, update_totals! viene chiamato che ricalcola i totali e quindi salva! viene chiamato, che attiva l'errore di convalida (questo errore si verifica molto raramente ma solo quando ho effettuato l'accesso e non sono stato in grado di trovarne la causa). Il modello di ordine ha due convalide nel suo modello:

validates_numericality_of :item_total 
    validates_numericality_of :total 

ho registrato order.item_total.inspect, order.total.inspect e order.errors.full_messages.inspect e ottenuto questo:

Wed Jan 25 08:53:08 -0800 2012order item total: #<BigDecimal:15780c60,'0.279E2',8(16)> 
Wed Jan 25 08:53:08 -0800 2012order total: #<BigDecimal:152bf410,'0.2448225E2',12(20)> 
Wed Jan 25 08:53:08 -0800 2012: ERRORS SAVING ORDER: 
Wed Jan 25 08:53:08 -0800 2012[] 

item_total e total sono memorizzati nel database mySQL come decimali (8,2). L'ultima riga è order.errors.full_messages.inspect, che è una matrice vuota. L'errore di convalida si presenta così:

ActiveRecord::RecordInvalid (Validation failed: {{errors}}): 
    vendor/extensions/mgx_core/app/models/order.rb:382:in `update_totals!' 
    vendor/extensions/mgx_core/app/controllers/line_items_controller.rb:7:in `destroy' 
    app/middleware/flash_session_cookie_middleware.rb:19:in `call' 
    C:\Users\mgx\My Documents\Aptana Studio 3 Workspace\catalogue-spree\script\server:3 
    c:/Ruby187/lib/ruby/gems/1.8/gems/ruby-debug-ide-0.4.16/lib/ruby-debug-ide.rb:112:in `debug_load' 
    c:/Ruby187/lib/ruby/gems/1.8/gems/ruby-debug-ide-0.4.16/lib/ruby-debug-ide.rb:112:in `debug_program' 
    c:/Ruby187/lib/ruby/gems/1.8/gems/ruby-debug-ide-0.4.16/bin/rdebug-ide:87 
    c:/Ruby187/bin/rdebug-ide:19:in `load' 
    c:/Ruby187/bin/rdebug-ide:19 

Credo che la mia domanda è duplice:

1. Perché il mio modello errori ActiveRecord non dicendo quello che l'errore di convalida è?

2. Come posso risolvere questo problema? Il mio item_total e il totale sono validi per il salvataggio come decimale (8,2)?

Sto usando le rotaie 2.3.5 e 0.10.2 baldoria

+0

Come stai recuperando l'ordine e line_item dal db (cioè cosa c'è nell'azione del tuo controller)? –

+0

Quando un utente preme il pulsante Rimuovi nel carrello degli acquisti, chiama una funzione chiamata destroy nel controller line_items. Il codice per distruggere è: 'Line_Item = LineItem.find (params [: id],: include =>: ordine) order = line_item.order line_item.destroy order.update_totals' update_totals!! fa alcuni calcoli per calcolare nuovi totali e poi chiama self.save! che attiva l'errore di convalida – Zyren

+0

Nel caso, ma LineItem distrugge l'ordine quando viene distrutto? In altre parole, sei sicuro che l'ordine stesso sia ancora valido prima di aggiornare i totali? salvare! dovrebbe gettare un'eccezione su un errore di convalida, quindi penso che tu vedresti l'errore nei tuoi log o qualsiasi altra cosa. –

risposta

25

quando si ha before_validation dichiarazioni e se tornano false allora si otterrà un messaggio Validation failed (ActiveRecord::RecordInvalid) con un messaggio di errore vuota (se non ci sono altri errori).

noti che before_validation callback non devono tornare false (nil va bene) e questo può avvenire per caso, per esempio, se si sta assegnando false ad un attributo booleano nell'ultima riga all'interno di quel metodo di callback.Scrivere in modo esplicito return true nella vostra callback metodi per fare questo lavoro (o solo true alla fine se il vostro callback è un blocco (come notato da Jesse Wolgamott nei commenti)).

UPDATE: Questo non sarà più un problema di partenza Rails 5.0, come return false sarà più arrestare la catena callback (throw :abort verrà ora arrestare la catena callback).

AGGIORNAMENTO: Si potrebbe anche ricevere ActiveRecord::RecordNotSaved: Failed to save the record se un callback restituisce false.

+1

Questo ha funzionato alla grande! Un aggiornamento: devi scrivere "true" alla fine del tuo blocco before_validation. "return true" fallirà poiché è in un blocco. –

+0

Grazie a @JesseWolgamott, ho aggiornato la risposta. –

+0

questo include anche 'before_save' Immagino, dal momento che scrivere' nil' come ultima riga del mio prima di salvare risolto questo! –

0

Credo che il problema risiede nel codice del controller. La variabile dell'ordine viene impostata prima che l'elemento pubblicitario venga distrutto e non è a conoscenza che è stato distrutto in seguito. Questo codice dovrebbe essere nel modello:

# line_item.rb 
after_destroy :update_totals! 
delegate :update_totals, :to=> :order 

E il controller dovrebbe solo distruggere l'elemento pubblicitario.

0

Riguardo a 1. Perché il mio errore di file activerecord non dice cosa è l'errore di convalida?, vedi se hai la gemma i18n installata. Se lo fai, prova a disinstallare o una versione precedente della gemma i18n.

gem uninstall i18n 
0

Mi sembra che tu stia utilizzando Ruby 1.8.7. Hai provato a eseguire la tua app utilizzando Ruby 1.9.3?

Problemi correlati