2012-06-18 15 views
5

İşte benim modelinde kullanıyorum ne:Rails'de doğrulamadan önce dolar işaretlerini nasıl bir değerden ayırırım?

before_validation :strip_dollar_sign 

validates :amount_due, 
      :format => { :with => /^\d+??(?:\.\d{0,2})?$/ }, 
      :numericality => {:greater_than => 0} 

private 

def strip_dollar_sign 
    self.amount_due = self.amount_due.to_s.tr!('$,','').to_f 
end 

Ben istiyorum tam olarak ne olsun Raylar Konsolu elle strip_dollar_sign işlevinden çizgiyi çalıştırırsanız (yani 400 $ 400.0 olarak biter) ama ne zaman Uygulamamdaki asıl formu kullanıyorum, değer her zaman 0.0 olarak biter. Yanlış yaptığım şeyi yakalayan var mı?

+3

para, veritabanında ve veri tabanında ondalık ve Ruby'de BigDecimal olarak depolanmamalıdır. Şamandıralar, beklenmedik sonuçlara neden olabilecek yuvarlama hataları olabilir. – DGM

cevap

14

Üç sorunlar: his answer yılında Stefan işaret ettiği gibi

  • , bunu bir $ değiştirilmesini etkilemez, gerçi tr! çağrısında , kaldırmak isteyebilirsiniz.

  • tr! kullanıyorsunuz ve dönüş değerini yanlış bir şekilde kullanıyorsunuz. tr! (Ruby'nin ! yöntem varyantlarının çoğunun yanı sıra), orijinal dizede hiçbir değişiklik yapılmadıysa nil değerini döndürür. nil.to_f, 0.0 olduğundan, bu yüzden bunu elde ediyorsunuz (veya belki de aşağıya bakın). Bunun yerine tr kullanmalısınız.

  • Raylar otomatik olarak ilişkili veritabanı sütun için doğru türe atama argümanları dönüştürür, böylece bile doğrulama önce değer bir yüzen dönüştürülür ediliyor ve "$400".to_f0.0 olduğunu ve geri arama görür budur. Solüsyon yerine geri arama kullanmanın amount_due= geçersiz kılmak için: Ben javascript bunu tavsiye

    def amount_due=(value) 
        value = value.to_s.tr('$', '').to_f 
        write_attribute(:amount_due, value) 
    end 
    
+1

Aslında 'tr' çağrısındaki virgül iyidir (ayrıca muhtemelen istenmeyen): "$ 500" .tr ("$,", '') '. Dokümanları alıntılamak için: "str'nin bir kopyasını, from_str içindeki karakterlerle birlikte, to_str içindeki karşılık gelen karakterlerle değiştirir. To_str, from_str'den daha kısasa, yazışmayı sürdürmek için son karakteri ile doldurulur." –

+0

@MichaelKohl İyi bir nokta, $ $ 'nin yerini etkilemediğini not etmek için düzenlenmiş, ancak bazı lokallerde virgül bir sınırlayıcı olduğu için yine de istenmeyen olabilir (ayrıca OP'nin Stefan'ın yanıtında ima edilmiş gibi görünüyor. bir hataydı). –

+0

Sanırım burada bir şey var, ama başka bir şey hala kırık. Eğer konsolda gidip 'amount_due =" $ 400 "'i çalıştırırsam ve' amount_due.to_s.tr (' $ ',' ') .to_f' çalıştırırsam çıktı 400.0'dır. Ama eğer bir nesne yaratırsam ve ''amount_due' değerine aynı $ 400'ı atamaya çalışırsam, hala '0.0' alırım. – richrad

3

$'dan sonra bir virgül var, böylece $ yerine $, kaldırabilirsiniz. Burada

+0

İyi yakalama! Ama hala 0.0 tükürüyor. – richrad

-2

. Rails, sayısal bir veritabanı türü tarafından desteklenen bir alandaki herhangi bir sayısal olmayan değeri 0.0'a çevirecek form yardımcılarıyla bazı sihir yapıyor gibi görünüyor. Aptal, biliyorum.

+0

OP, Rails'de (etiketleri görebileceğiniz gibi) çözüm istemektedir, bu yüzden JS kendi sorusuna bir cevap değildir. –

İlgili konular