Non sarebbe meglio avere comunque un campo decimal?
Si avete ragione, nemmeno il Float va bene, dovrei tenermi il campo come
centesimi anche dentro l’applicazione ruby, non solo a db. ma devo
trovare
un sitema che il to_s mi faccia sempre la divisione e formattazione del
numero in modo che nelle view posso sempre usare @ estimate.discount e
anche
gli helper dei form funzionino bene di default (cioè non voglio fare @
estimate.discount.format_two_decimals).
Ho pensato di risolvere questo riscrivendo to_s come singleton method di
discount ogni volta che lo leggo da DB in modo da avere un Fixnum che
contiene i centesimi ma viene stampato correttamente (ovvero diviso per
100)
Ho provato a farlo così ma non riesco a farlo funzionare ancora:
discount #=> Fixnum 3334 (ovvero sconto del 33.34%)
discount.to_s #=> String 3334
discount.set_default_format
discount.to_s #=> String 33.34 (questo è quello che voglio ottenere)
implementato
così:
class Fixnum
def set_default_format
class << self
def to_s
‘%.2f’ % self.to_f /100
end
end
end
end
Non so perchè ma mi da un TypeError: can’t define singleton method “to_s”
for Fixnum
anche se mi pare corretto…
io avrei usato una coppia di accessor da ruby (con
attr) e poi inserito una regola before_save, ma così è
effettivamente più consistente
Mi pare che con attr faccia casino perchè in activerecord gli attributi
non sono attributi veri ma stanno memorizzati da qualche altra parte,
quindi
usando attr si incasina e qualche helper va in loop… o perlomeno
così avevo
letto in giro… non so di per certo, ma questo è il motivo per cui ho
fatto
così…
I consigli di Gabriele funzionano e sono arrivato a questo:
require ‘active_record’
module StoreAsCents
def store_as_cents(field_sym)
define_method("#{field_sym}=") do |value|
write_attribute(field_sym, (value.to_f * 100).to_i)
end
define_method("#{field_sym}") do
value = read_attribute(field_sym)
value.to_f / 100
end
end
end
includes new methods
ActiveRecord::Base.class_eval do
extend StoreAsCents
end
Che già mi pare un pò meglio. Altri hints?