2014-05-23 10 views
15

Ho modelli/forme complicate. Non voglio record ripetuti, quindi voglio unire record con attributi simili. Come cancellerei "save" usando un callback before_save? Questo è quello che sto pensando:Rails 4: Come cancellare salvare su un callback "before_save"?

class ProductsColor < ActiveRecord::Base 


    before_save :check_for_similar_record 

    def check_for_similar_record 
    if ProductsColor.exist?(color_id: self.color_id, product_id: self.product_id) 
     # merge values with existing ProductsColor and stop self from saving 
    end 
    end 

end 

risposta

22

Per evitare record da essere salvati, si dovrebbe semplicemente ritorni false:

def check_for_similar_record 
    if ProductsColor.exists?(color_id: self.color_id, product_id: self.product_id) 
    # merge values 
    false 
    else 
    true 
    end 
end 
+11

il record verrà comunque salvato se si restituisce nil, è necessario restituire esplicitamente false per annullare il salvataggio. – dezman

+1

Questo non è più vero a partire da Rails 5 - vedere l'altra risposta per i dettagli. –

+0

@JonGjengset la domanda era "Rails 4: Come annullare salvare su un callback" before_save "?". Ho avuto questo voto negativo per questo? –

40

Rails 5

As of Rails 5, si può segnalare che l'operazione dovrebbe essere interrotto chiamando esplicitamente throw :abort all'interno della richiamata. La sezione relativa alla documentazione sul cancelling callbacks (ora) afferma:

Se un before_* richiamata throws :abort, tutti i richiami più tardi e l'azione associata vengono annullate.

La sezione seguente transactions continua:

Se un callback before_* annulla l'azione di un ROLLBACK viene rilasciato. È inoltre possibile attivare un aumento di ROLLBACK in qualsiasi callback, inclusi gli hook after_*.

Rails 4

La storia è abbastanza simile a quella con Rails 5, se non che i callback devono invece restituire false. Le parti corrispondenti dei the documentation afferma utilmente

Se un callback before_* restituisce false, tutti i richiami successivi e l'azione associata vengono annullati. Se un after_ * callback restituisce false, tutte le callback successive vengono annullate.

Seguito da

Se un before_ * callback annulla l'azione di un ROLLBACK viene rilasciato. Puoi anche attivare un ROLLBACK che genera un'eccezione in qualsiasi callback, compresi gli hook after_ *.

+0

Vedere anche: ** Rails 5 interruzione del lancio: come configurare i messaggi di errore? ** http://stackoverflow.com/questions/38625276/rails-5-throw-abort-how-do-i-setup- messaggi di errore – prograils

+0

Cosa succede se lo si desidera silenziosamente non salvare? per esempio. evitare associazioni duplicate in una tabella di associazione. Non c'è bisogno di lanciare un errore in questo caso ... Rails 5 – Micah

Problemi correlati