Przecinek dziesiętny?

Jak rozwiązujecie problem przecinka dziesiętnego w formularzach z tabeli?

Polska ortografia i przyzwyczajenia użytkowników nakazują stosować przecinek dziesiętny.

W formularzach niepowiązanyc z tabelą można zrobić gsub(’.’, ‘,’) (lub odwrotnie przy czytaniu params) w polach zawierających dane numeryczne.
Ale jak to generalnie zrobić dla tabeli - dla pół :decimal lub :float ?
gsuba też możnaby robić ale jak formularz generuje się sam a potem jest od razu update_attributes to nie ma jak tego wepchnąć.
Pewnie dałoby się zrobić jakiś automat działający w dwie strony i obsługujący validates_numericality_of.

before_validate na przykład? No niestety, trzeba to “ręcznie” podmienić, tj. (g)subem.

Ew. nadpisać setter dla tego atrybutu:

clas MyClass < ActiveRecord::Base def foo=(foo) foo.gsub!(",", ".") super end end

czasem się zdarzy np: “12,340.324”

[code=ruby]class Float
def to_fs(opts={})
delimiter=opts[:delimiter] || “”
separator=opts[:separator] || “,”
parts = to_s.split(’.’)
parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, “\1#{delimiter}”)
parts.join(separator)
end
end
class String
def to_fs(opts={})
Float(gsub(’,’,’.’))
end
end

n= 1234.43.to_fs #=> “1234,43”
n.to_fs #=> 1234.43[/code]
nie ładnie ale działa

poczytaj tu:
http://api.rubyonrails.org/classes/ActionView/Helpers/NumberHelper.html

edit: oczywiście głupoty popisałem :slight_smile: / poprawione

@radarek: super to brzydkie wywołanie, to już lepiej przez attributes[:foo] :slight_smile:

Tomash: dlaczego brzydkie? ja tak często gęsto robię w kodzie i nie zauważyłem minusów, normalne OO (albo mi się tak tylko wydaje) ;]

Bo możesz mieć z tym problemy przy np. STI :slight_smile:

STI też jest ponoć złem, więc jak się zrezygnuje z STI, to nie ma problemu z super :wink:

A tak na serio to rzeczywiście, o tym nie pomyślałem - może dlatego, że rzadko korzystam z STI.

Tzn. ogólnie “nigdy nie wiesz kto jest po drugiej stronie” – jeśli attributes[:key] pozwala się dobrać do “surowego” atrybutu z gwarancją braku pośredników, to ja zdecydowanie wolę takie rozwiązanie niż super i modlenie się żeby któryś plugin mi gdzieś-po-drodze nie namieszał w łańcuchu wywołań. :wink:

(nienawidzę monkeypatchingu, czy już o tym pisałem? :stuck_out_tongue: )

Jak tak sobie myślę nad tym, to i tak wszystko zależy od sytuacji. Jeżeli jeden model dziedziczy po drugim, to czasami wskazane by było, żeby aplikowały się też writery. W każdym razie w tym akurat wypadku nie ma chyba jednego “dobrego” wyjścia :slight_smile:

Możesz rozwinąć? Nie widzę za bardzo związku z STI.

[quote=Tomash]Tzn. ogólnie “nigdy nie wiesz kto jest po drugiej stronie” – jeśli attributes[:key] pozwala się dobrać do “surowego” atrybutu z gwarancją braku pośredników, to ja zdecydowanie wolę takie rozwiązanie niż super i modlenie się żeby któryś plugin mi gdzieś-po-drodze nie namieszał w łańcuchu wywołań. :wink:

(nienawidzę monkeypatchingu, czy już o tym pisałem? :stuck_out_tongue: )[/quote]
No to pretensje do tych co używają MP ;). Jeśli chodzi o moje rozwiązanie to uważam je za dobre. A jak railsy zmienią implementację i self[:foo] nie będzie działać to co?

Dzięki za wskazówki. Działające u mnie rozwiązanie poniżej.
W modelach dodaję dla wybranych pól:

validates_numericality_of :kwota, :allow_blank=>true def kwota=(x) x=x.to_s.sub(',','.').gsub(' ','') super end
sub dla przecinka - bo dwa przecinki wyłapie walidacja. Zapis z kropką dziesiętną też przejdzie.
A separatorem tysięcy może być spacja lub _ . W miarę elastyczne dla użytkowników.
W helperze do formularza:

case type ... when 'decimal' value = record.respond_to?(name + "_before_type_cast") ? record.send(name + "_before_type_cast") : record.send(name) params[:value]= value.to_s.sub('.',',') cont.text_field name, params ...
I na razie jest ok …