2012-05-23 4 views
17

Ho una domanda da principianti. Come posso verificare che l'oggetto del modello sia valido con i nuovi parametri PRIMA di aggiornarlo?Rails 3 - controlla che l'oggetto sia valido con params prima dell'aggiornamento

voglio trasformarla:

def update 
    @obj = SomeModel.find(params[:id]) 

    if @obj.update_attributes(params[:obj]) 
    # That have been updated 
    else 
    # Ups, errors! 
    end 
end 

Per una cosa del genere:

def update 
    @obj = SomeModel.find(params[:id]) 

    if @obj.valid_with_new_params(params[:obj]) 
    @obj.update_attributes(params[:obj]) 
    else 
    # Ups, errors! 
    end 
end 

risposta

35

Per aggiornare gli attributi senza salvarli, è possibile utilizzare

@obj.assign_attributes(params[:obj]) 

Quindi per verificare se l'oggetto è valido, è possibile chiamare

@obj.valid? 

Se l'oggetto è non valida , È possibile vedere gli errori (solo dopo aver chiamato .valid?) chiamando

@obj.errors 

Se l'oggetto è valida, è possibile salvarlo chiamando

@obj.save 

Tuttavia, tutto questo solito non è necessario Se l'oggetto non è valido, ActiveRecord non salverà l'oggetto nel database, quindi tutte le modifiche agli attributi verranno dimenticate quando si lascia l'azione del controller.

Inoltre, dal momento che un record non valido, non verrà salvato nel database, si può sempre chiamare Object.find() di nuovo per ottenere l'oggetto originale indietro.

+4

Dopo @ obj.attributes (params [: obj]), chiama @ obj.save. –

+0

Il metodo 'attributes()' come mostrato in questa risposta al momento della stesura di questo articolo è deprecato. Usa invece 'assign_attributes (new_attributes)' o l'alias 'attributes = (new_attributes)'. Quindi la prima riga di questa risposta dovrebbe essere '@ obj.assign_attributes (params [: obj])'. Vedi [ActiveRecord :: AttributeAssignment] (http://api.rubyonrails.org/classes/ActiveRecord/AttributeAssignment.html) – user664833

+0

Re: 'assign_attributes (new_attributes)' - nota che * gli unici attributi impostati sono quelli nominati con le chiavi in l'hash dei parametri *. Quindi se hai un oggetto esistente, puoi aggiungere/unire solo un sottoinsieme di attributi. – user664833

0

L'oggetto non viene salvato se l'argomento passato non produce un oggetto valido, in modo da poter usa la tua strada bene. È possibile visualizzare gli errori (se presenti) utilizzando l'array @obj.errors.

0

update_attributes metodo validate object e restituisce false se object non è valido. Quindi, si può solo scrivere:

if @obj.update_attributes(params[:obj]) 
    # That have been update 
else 
    # Ups, errors! 
end 
3

È possibile chiamare il metodo valid? per eseguire le convalide.

Ciò non garantisce che un salvataggio successivo avrà esito positivo se alcune delle convalide dipendono dallo stato di altri oggetti nel database. Te risparmio potrebbe anche fallire per motivi estranei a convalide (ad esempio, un vincolo di chiave esterna)

io non sono sicuro perché ci si vuole questo schema

+1

Mi risparmio pochi oggetti di diversi modelli. Quindi raccolgo errori di convalida di ciascun modello e poi lo mostro in un popup. – ExiRe

0

La risposta è che si può definire un metodo

def valid_with_new_params(hash) 
    self.attributes = hash 
    valid? 
end 

Ma sarebbe inutile perché @obj.update_attributes(params[:obj]) restituisce true se l'obj è stato aggiornato con successo e false altrimenti. Si noti inoltre che internamente il metodo update_attributes esegue tutte le convalide su @obj in modo che sia disponibile @obj.errors se l'aggiornamento non è riuscito.

+1

'attributes =' metodo è deprecato nelle nuove versioni di Rails – apneadiving

+0

Grazie @apneadiving non lo sapevo :) – Gerry

0

Per aggiornare gli attributi senza

@obj.attributes = params[:obj] 0r 
@obj.attributes = {:name => “Rob”} 

risparmio Per poi verificare se l'oggetto è valido

@obj.valid? 

Per controllare se c'è qualche errore

@obj.errors