2016-01-13 21 views
8

C'è qualche vantaggio nell'avere validazioni per campi booleani di modelli?Per convalidare o non convalidare il campo booleano

ho avuto una convalida per garantire la presenza di un campo booleano

validates :boolean_attribute, presence: true 

E 'fallito quando boolean_attribute era falso. Ho cercato su Google e ho trovato queste domande su SO relative al problema.

Rails database defaults and model validation for Boolean fields
Rails validates_presence not validating on Boolean?

poi aggiunti questa convalida invece

validates :field, :inclusion => {:in => [true, false]} 

Questo mi ha fatto pensare. Ho bisogno di validazioni per i campi booleani? Il suo valore sarà sempre vero o falso o nullo giusto? Anche se qualcuno tenta maliziosamente di cambiarlo per dire, un numero, il tipo non si prenderà cura di esso? O c'è un po 'di sicurezza che fornisce la convalida dell'inclusione di cui sopra?

+0

sì, di solito non mi preoccupo. Se il campo è obbligatorio, puoi usare il trucco di inclusione sopra e per essere sicuro di mettere "nullo: falso" sulla colonna –

+0

Se hai bisogno che il valore sia 'true' o' false' ma non 'nil' allora vuoi usare la convalida. Se 'true',' false' e ​​'nil' sono a posto, non è necessaria la convalida. Quale di questi è giusto per te dipende interamente dal tuo caso d'uso. –

+0

@Jordan: Sto bene con zero fino a quando ruby ​​lo convalida a false e non ci sono scenari che potrebbero interrompere il sistema. Ci sono? –

risposta

8

Se è necessario convalidare o meno un attributo booleano per l'inclusione in [ true, false ] dipende interamente dal caso d'uso.

Hai correttamente identificato che, in assenza di validazione di altro codice, un campo booleano in Rails sarà sempre (dopo il tipo di coercizione) true, false o nil. Rails non costringerà nil a false. Se imposti l'attributo booleano di un modello su nil e lo salvi, l'attributo sarà nil, non false, quando lo recupererai dal database in un secondo momento.

Si può pensare a nil come a un "terzo stato" per un campo booleano. Considera una semplice app di sondaggio che consente agli utenti di salvare un sondaggio incompleto da completare in seguito. Supponiamo che un utente salvi un sondaggio incompleto con la domanda "Mangi carne?" senza risposta. Non si desidera memorizzare false nel database poiché ciò significherebbe che l'utente ha risposto "no". Quando l'utente torna per terminare il sondaggio, si desidera che tale domanda rimanga senza risposta, quindi si desidera memorizzare nil nel database.

In casi come sopra, è opportuno (e necessario) non convalidare per l'inclusione in [ true, false ].

Tuttavia, come regola generale direi che in tutti gli altri casi, vale a dire. in ogni caso in cui non si dispone di uno specifico , occorre per i valori nil: è necessario convalidare i campi booleani per l'inclusione in [ true, false ].

Naturalmente, se si fa permettono nil è necessario fare attenzione perché, come sapete, è un valore nilFalsey in Ruby. Dovrai controllare esplicitamente "nilness" in luoghi in cui potresti altrimenti affidarti alla verità o alla falsità di un valore. Cioè, invece di questo:

if !is_meat_eater 
    unanswered_questions << :is_meat_eater 
end 

... che non si comportano come previsto se is_meat_eater è false, è necessario controllare in modo esplicito per nil:

if is_meat_eater.nil? 
    unanswered_questions << :is_meat_eater 
end 
+0

Thankyou @Jordan +1 per lo scenario. –

+0

upvoted per lo sforzo :) –

0

Se si desidera la convalida del tipo reale, direi controllare la gemma validates_type. Condurrà la convalida sul tuo attributo prima della coercizione di tipo. La coercizione di tipo può avere un comportamento imprevisto, this answer mostra come solo un determinato insieme di valori è "vero".

Se si accetta uno Boolean per essere nil, non è proprio un Boolean giusto? Quello è true, false o un terzo valore, nil.

4

Non è necessario per convalidare un campo boolean, se non è vero è falso.

Basta set a "default" in your db in modo che il bool sta andando sempre di avere un certo valore non importa quale:

#db/migrate/add_boolean_column_______.rb 
class AddBooleanColumn < ActiveRecord::Migration 
    def change 
     change_table :table do |t| 
     t.boolean :field, default: false 
     end 
    end 
end 

In questo modo, non avrei nemmeno includere eventuali convalide. Il sistema assicurerà che lo imposti come vero o falso, che spetta a te come sviluppatore.