2010-01-18 10 views
5

Ho una tabella con una colonna denominata lifecycle_id e un'altra chiamata lifecycle_change_reason. lifeycle_id viene normalmente modificato automaticamente dal sistema in base ad altri fattori, ma alcuni utenti hanno la possibilità di modificare manualmente il ciclo di vita. se lo fanno, vorrei chiedere loro di fornire una ragione per il cambiamento, ma non voglio richiedere quel campo in nessun altro momento. qualcuno ha un suggerimento su come posso eseguire questo tipo di convalida?come convalidare la presenza di un campo solo se un altro campo è stato modificato nelle guide?

thx :)

-C

risposta

0

posso vedere un paio di modi diversi. I penso il migliore sarebbe aggiungere un altro campo alla tabella chiamato qualcosa come lifecycle_id_original. Allora il vostro modello sarebbe includere il codice come questo:

class Member < ActiveRecord::Base 
    belongs_to :lifecycle 

    validates :lifecycle_change_reason, :if => :lifecycle_changed? 

    before_save :reset_original_lifecycle 

    protected 

    def lifecycle_changed? 
    self.life_cycle_id != self.lifecycle_id_original && !self.lifecycle_id_original.nil? 
    end 

    def reset_original_lifecycle 
    self.lifecycle_id_original = self.lifecycle_id 
    end 
end 

Quando l'oggetto (elemento in questo esempio) viene convalidato, sarà richiesto solo lifecycle_change_reason quando l'originale e lifecycle_id non sono identici. Un valore nullo è anche consentito per l'originale, perché è quello che sarà quando un record è stato appena creato.

Quindi, quando viene salvato, "originale" viene impostato in modo che corrisponda a lifecycle_id, quindi il prossimo ciclo di aggiornamento funzionerà correttamente.

Questo non è pulito come mi piacerebbe. Il mio primo pensiero è stato quello di utilizzare un attr_accessor in modo che il duplicato non venga sempre memorizzato nel DB, ma ciò significherebbe impostare tale valore ogni volta che viene caricato un record. Non sono a conoscenza di alcun callback in stile on_load per i modelli ActiveRecord.

-1

Sembra questo il controller. Mi rendo conto che la gente vuole spingere la logica ai modelli, e per una buona ragione, ma siamo pragmatici qui: se il tuo sistema sta cambiando questo valore automaticamente, e c'è solo un punto nel tuo sistema in cui qualcuno può cambiarlo manualmente, lo fa non, a mio parere, introdurre tutta questa complessità per far rispettare semplicemente l'esistenza di un motivo nel controller con qualcosa di semplice:

if params[:object_name][:life_cycle_id] != @object.life_cycle_id && params[:object_name][:life_cycle_change_reason].blank? 
    flash[:error] = "You must enter a reason for changing the life cycle." 
    redirect_to :back and return false # or whatever 
end 
+0

il problema con questo è che non si ottiene tutto il bel errore di convalida di gestione in il modulo. –

+0

Sicuramente lo sai fare anche tu: @ object.errors.add (: life_cycle_change_reason, "deve essere fornito.") Semplice. – adriandz

Problemi correlati