Mongoid menempatkan nilai float pada bidang ketika string diberikan

Saya menggunakan Ruby 1.9.3-p448 dan Rails 3.2.13. Saya memiliki model sederhana ini dengan validasi format float:

class User
  include Mongoid::Document
  include Mongoid::Timestamps

  field :height, type: Float
  field :weight, type: Float

  validates :height, presence: true, format: { with: /[-+]?[0-9]*\.?[0-9]+/ }
  validates :weight, presence: true, format: { with: /[-+]?[0-9]*\.?[0-9]+/ }

end

Jika saya menjalankan kode ini:

test = User.new(height:"hi", weight:"try")

Ini memberi saya hasil berikut:

#<User _id: 51f67b49781018056b000008, created_at: nil, updated_at: nil, height: 0.0,width: 0.0> 

Mengapa mongoid memberi nilai 0,0 jika saya memasukkan string? Saya mengharapkan kesalahan validasi.


person Alberto Pellizzon    schedule 29.07.2013    source sumber
comment
Kesalahan apa yang Anda harapkan?   -  person toro2k    schedule 29.07.2013
comment
saya mengharapkan kesalahan validasi format   -  person Alberto Pellizzon    schedule 29.07.2013
comment
juga ketika saya menjalankan User.validators di konsol ia mencetak [#‹Mongoid::Validations::PresenceValidator:0xa7e51d0 @attributes=[:height], @options={}›, # ‹Mongoid::Validations::PresenceValidator:0xa7e38d0 @ atribut=[:berat], @options={}›, #‹Mongoid::Validasi::PresenceValidator:0xa907824 @attributes=[:chest], @options={}›]   -  person Alberto Pellizzon    schedule 29.07.2013


Jawaban (2)


Anda tidak mendapatkan kesalahan validasi karena metode new tidak memicu validasi, untuk melihatnya Anda harus menjalankan:

User.create!(height:"hi", weight:"try")
# .../mongoid-3.1.0/lib/mongoid/persistence.rb:335:in `fail_validate!': (Mongoid::Errors::Validations)
# Problem:
#   Validation of User failed.
# Summary:
#   The following errors were found: Height is invalid, Weight is invalid
# ...

Mengingat bahwa, bidang height dan weight diisi dengan 0.0 karena Strings dikonversi ke Float menggunakan metode to_f, yang berperilaku seperti ini:

'foo'.to_f
# => 0.0

Selain itu, tidak ada gunanya memvalidasi bidang floating point menggunakan ekspresi reguler karena konversi ke Float dilakukan sebelum validasi, sehingga validasi selalu gagal karena perilaku =~:

1.2 =~ /any_regexp/
# => nil


Pembaruan Untuk memvalidasi bahwa, jika diberikan sebagai string, bidang tersebut adalah nomor yang valid, Anda dapat menggunakan opsi numericality:

class User
  # ...
  validates :height, presence: true, numericality: true
  # ...
end

User.create!(height: '0.0')
# => #<User ... >

User.create!(height: 'foo')
# Problem:
#  Validation of User failed.
# ...
person toro2k    schedule 29.07.2013
comment
Itulah masalah saya, terima kasih! Jadi saya harus memeriksa format di sisi klien atau bisakah saya melakukannya di sisi server dengan cara lain? - person Alberto Pellizzon; 29.07.2013

MongoDB menyimpan data dalam format biner yang disebut BSON yang mendukung tipe data numerik berikut:

  • int32 - 4 byte (bilangan bulat bertanda 32-bit)
  • int64 - 8 byte (bilangan bulat bertanda 64-bit)
  • double - 8 byte (titik mengambang IEEE 754 64-bit)

Tidak ada nilai pasti titik tetap yang setara dengan tipe desimal mySQL di MongoDB, tetapi Anda dapat menyimpan angka floating point 64-bit di Mongo sebagai ganda.

Perlu disebutkan bahwa shell MongoDB - sebagai shell JavaScript - tidak mengenali perbedaan antara nilai integer dan floating-point, ia memperlakukan semua angka dengan sama karena JavaScript mewakili semua angka sebagai floating point 64-bit, terlepas dari BSON yang mendasarinya jenis.

Namun, sebagian besar driver bahasa MongoDB membedakan antara tipe integer dan floating point.

Dari -> Apakah MongoDB mendukung tipe floating point?

person Mini John    schedule 29.07.2013
comment
saya menggunakan mongoid dan saya tidak dapat menentukan Double sebagai tipe data saya hanya memiliki Flaot two.mongoid. org/docs/documents/fields.html - person Alberto Pellizzon; 29.07.2013
comment
Tidak disukai, karena ini adalah salinan persis dari jawaban ini. Jika jawabannya seharusnya sama maka tautkan saja ke pertanyaan lain. - person Jon Cairns; 29.07.2013