2010-07-27 6 views
3

considère que j'ai une migration comme suitne peut pas comprendre rails activerecord raisons transtypage

create_table :dummies do |t| 
    t.decimal :the_dummy_number 
end 

i instancier comme le

suivant
dummy = Dummy.new 
dummy.the_dummy_number = "a string" 
puts dummy.the_dummy_number 

la sortie de ce qui précède est

0.0 

comment est-ce arrivé? puisque j'attribuer une mauvaise valeur ne devrait-elle pas soulever une erreur?

Le plus gros problème est le suivant.

Puisqu'il convertit automatiquement ma valider la méthode échoue lamentablement.

mise à jour validate -la méthode

validate :is_dummy_number_valid, :the_dummy_number 
def is_dummy_number_valid 
    read_attribute(:the_dummy_number).strip() 
end 
+0

Quelle méthode de validation utilisez-vous? si vous utilisez 'validates_numericality_of: the_dummy_number' cela devrait fonctionner correctement –

+0

consultez la mise à jour – ZX12R

+0

Votre méthode de validation ne fait aucune validation! –

Répondre

3

La raison pour laquelle cela ne fonctionne pas comme prévu que la mise en œuvre rubis sous-jacente de BigDecimal ne pas l'erreur lorsqu'il est passé une chaîne.

Consultez le code suivant

[ 'This is a string', '2is a string', '2.3 is also a string', 
    ' -3.3 is also a string'].each { |d| puts "#{d} = #{BigDecimal.new(d)}" } 

This is a string = 0.0 
2is a string = 2.0 
2.3 is also a string = 2.3 
    -3.3 is also a string = -3.3 

Alors BigDecimal scanne la chaîne et attribue quoi que ce soit au début de la chaîne qui pourrait être une décimale à sa valeur.

Si vous définissez votre modèle comme ça

class Dummy < ActiveRecord::Base 

    validates_numericality_of :the_dummy_number 

end 

Ensuite, la validation devrait fonctionner correctement

>> d=Dummy.new(:the_dummy_number => 'This is a string') 
=> #<Dummy id: nil, the_dummy_number: #<BigDecimal:5b9230,'0.0',4(4)>, created_at: nil, updated_at: nil> 

>> puts d.the_dummy_number 
0.0 
=> nil 
>> d.valid? 
=> false 

>> d.errors 
=> #<ActiveRecord::Errors:0x5af6b8 @errors=#<OrderedHash 
    {"the_dummy_number"=>[#<ActiveRecord::Error:0x5ae114 
    @message=:not_a_number, @options={:value=>"This is a string"} 

Cela fonctionne parce que la macro validates_numericality_of utilise la méthode RAW_VALUE pour obtenir la valeur avant qu'il ne soit catalogué et affecté à la valeur décimale interne.

+0

merci beaucoup .. – ZX12R

Questions connexes