Fwd: Sfida: miglior modo per generare metodi dinamicamente!

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 :slight_smile:

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?

for your information, ho implementato il codice che moltiplica i valori
delle colonne in un plugin rails che si chiama store_multiplied. Il
plugin è
di una banalità disarmante ma che vi posso dire, a me torna utile…
quindi
beccatevelo qui:
http://blog.seesaw.it/articles/2006/06/19/ruby-on-rails-plugin-store_multiplied

se avete idee di come risolvere meglio la questione, sono tutto orecchi,
non
mi dispiace per niente il fatto di sfruttare la vostra intelligenza per
sopperire alla mia mediocrità :smiley:
buona notte e un grazie di cuore per gli spunti su tutta la linea

PS: pare proprio che non si riesca a ridefinire il to_s sulle classi
tipo
Float o Numeric quindi sono dovuto ricorrere a degli accessors specifici
per
le stringhe formattate.

Paolo

Ho provato a farlo così ma non riesco a farlo funzionare ancora:

— Paolo Donà [email protected] ha scritto:

PS: pare proprio che non si riesca a ridefinire il
to_s sulle classi tipo
Float o Numeric quindi sono dovuto ricorrere a degli
accessors specifici per
le stringhe formattate.

mi ero scordato, volevo rispondere riguardo questo…
il problema è che non puoi definire singleton per
float e interi perché altrimenti arriveresti a cose
come 2+1=5 che ucciderebbero l’interprete :slight_smile:

Però puoi definire un metodo singleton per la
classe,usando un to_formatted_s o una cosa del genere,
o wrappare to_s per fargli prendere un argomento
simbolico (al momento prende in input solo la base, iirc)


icq: #69488917
blog it: http://riffraff.blogsome.com
blog en: http://www.riffraff.info

Chiacchiera con i tuoi amici in tempo reale!
Yahoo Search - Ricerca nel Web | Motore di Ricerca

On 6/20/06, gabriele renzi [email protected] wrote:

Però puoi definire un metodo singleton per la
classe,usando un to_formatted_s o una cosa del genere,

Grazie Gabriele, infatti in un primo momento volevo aggiungere un
Float.to_str.
Il problema però è che tutti gli helper di rails e ERB invocano
automaticamente it to_s quindi sostazialmente o mi ridefinivo tutti gli
helper o facevo un fake attribute formattato nei miei model che non fa
altro
che wrappare l’attributo persistente vero.

Praticamente ora i miei helper punteranno ad un discount_s invece che
discount.
Lo so che non è molto elegante come soluzione ma non vedo alternativa…

o wrappare to_s per fargli prendere un argomento

simbolico (al momento prende in input solo la base, iirc)

mmm… questa non l’ho capita, me la puoi spiegare meglio? intendi fare
un
alias e ridefnire to_s? tipo
così?
E:\prj\archeodata>irb
irb(main):002:0> class Float
irb(main):003:1> alias :old_to_s :to_s
irb(main):004:1> def to_s (format = false)
irb(main):005:2> return “FORMATTED” if format
irb(main):006:2> old_to_s
irb(main):007:2> end
irb(main):008:1> end
irb(main):009:0>
irb(main):010:0* 12.5.to_s #=> “12.5”
irb(main):011:0> 12.5.to_s true #=> “FORMATTED”
irb(main):012:0>

Solo che non vedo come posso fare in modo che tutti gli helper mi
chiamino
il to_s con un parametro…


Paolo Donà
email me: paolo[dot]dona[at]gmail[dot]com
skype me: paolo[dot]dona