2011-03-07 8 views
27

Ho il seguente modello:problema con il passare booleani per update_attributes

class GuestCatering < ActiveRecord::Base 

    # Validation 
    validates :name, :presence => true 
    validates :order_number, :presence => true 
    validates :orderable, :presence => true 

end 

Ma quando cercherò di aggiornare un GuestCatering esistente con il seguente codice:

guest_catering.update_attributes(:orderable => false) 

La ristorazione degli ospiti variabile è un oggetto GuestCatering valido. L'oggetto guest_catering ha errori dopo l'aggiornamento, così:

<{[:orderable, ["can't be blank"]]=>nil}> 

Ma quando passo un orderable => true, tutto va bene e nessun errore.

Cosa c'è di sbagliato qui, perché non posso impostare ordinabile su false?

+0

Prova questa: sembra – Ashish

+0

stesso errore – LeonS

risposta

39

Il modello è in realtà comporta esattamente come hai detto a, attraverso l'utilizzo del validates :orderable, :presence => true

Non ha molto senso convalidare la presenza di un flag booleano - che sta per essere true, nil o false - e in Ruby mondo , nil e false hanno lo stesso valore semantico quando si tratta di logica booleana.

Internamente, validates :presence si basa sul valore dell'attributo da controllare per restituire false quando viene chiamato blank?. E, in Rails (con ActiveSupport), false.blank? valuta come true - il che significa che il campo sta venendo a mancare la convalida.

sufficiente rimuovere che convalida e tutto funzionerà come previsto.

+0

: guest_catering.update_attributes (ordinabile => 0) Quindi non posso convalidare una bandiera booleana? – LeonS

+3

Come lo si convalida? È acceso o spento. Se vuoi che sia vero (come accettare i termini), puoi utilizzare una convalida per applicarla. Nel tuo caso, non sembra richiesto. –

+0

Grazie mi ha aiutato molto mi trovavo in una situazione simile –

-1

Invece di validates :presence => :true, si dovrebbe scrivere il migrazioni con il valore di default in questo modo:

t.boolean :orderable, :default => 0 

presumo il tuo valore di default dovrebbe essere false. Se true, utilizzare 1 come predefinito. Quindi imposterà il valore predefinito nel database. Quindi, puoi omettere il controllo di validazione.

La ragione per cui non è possibile utilizzare validates :presence si risponde con @ Dan. Presenza non significa vuoto e Rails usa .blank? funzione per questo e false.blank? è true

19

come Dan Cheail già detto nella sua risposta, un nil e false booleana è semanticamente la stessa cosa.

Ma, se si ha realmente bisogno per convalidarlo (non permettendo nil), si può sempre fare:

validates_inclusion_of :orderable, :in => [true, false]

+0

Se la colonna del database per il tuo booleano è 'NOT NULL', questa è la risposta corretta in quanto ciò convaliderà il campo prima di tentare di scrivere il record. L'altra risposta permetterà alla validazione di passare con 'nil', ma' .save' genererà un errore sulla restrizione della colonna. – dbcb