Forum: Rails-ES internacionalización de importes entrados

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
D48be99143e13e40d1c44a4da63a53f4?d=identicon&s=25 Mongeta 99 (raimon)
on 2009-05-04 11:25
Hola,

No he encontrado ninguna solución que me agrade al problema de entrar
valores numéricos en RoR, en diferentes formatos.

La gran diferencia está en los separadores de decimales y miles.

ES: 1.254,09
US: 1,254.09

He creado formatos por defecto y cualquier importe con .to_s sale en el
formato deseado, el problema lo tengo cuando recbio estos números por
parte del usuario, no he encontrado la manera que RoR haga la
transformación automáticamente, es decir, si el usuario entra 1254,09
RoR usa el valor 1254.00

Para que me funcione correctamente, he de cambiar cada valor uno por
uno, por ejemplo:

  def convert_european_number(value)

    value=value.gsub('.','')
    return value.to_s.gsub(',', '.').to_f

  end

he mirado la documentación de i18N pero únicamente sirve para display,
no para entrar importes ...

si esta es la única manera de hacerlo, ¿ alguna idea, indicación, ... de
cómo hacerlo lo más fácilmente posible ?


gracias por vuestra ayuda!

r.
7cc80e366962ecdea03eb1b150f6abf1?d=identicon&s=25 Fernando Val (aaromnido)
on 2009-05-04 14:58
(Received via mailing list)
Hola Raimon,

A mi se me ocurre a sí a votepronto, que descompongas el campo de
entrada en dos (cifra sín céntimos - céntimos) y entre medio pongas la
"," o el "." en función del idioma. Luego juntas los dos datos en uno
antes de cargarlo en la tabla. Y claro, eso sí, validas que no mentan
ni comas ni puntos en ambos campos.

Suerte.

El día 4 de mayo de 2009 11:25, Raimon Fs
<ruby-forum-incoming@andreas-s.net>
escribió:> He creado formatos por defecto y cualquier importe con .to_s sale en 
el
>    value=value.gsub('.','')
>
> gracias por vuestra ayuda!
>
> r.
> --
> Posted via http://www.ruby-forum.com/.
> _______________________________________________
> Ror-es mailing list
> Ror-es@lists.simplelogica.net
> http://lists.simplelogica.net/mailman/listinfo/ror-es
>



--
Fernando Val
Web Designer
http://www.fernandoval.es
D48be99143e13e40d1c44a4da63a53f4?d=identicon&s=25 Mongeta 99 (raimon)
on 2009-05-04 17:41
Lo veo complicado, luego hay un montón de cálculos con estos campos y
sería demasiado complicado.

Creo que se me escapa algo, porque no he visto mucho movimiento sobre
este tema, y me preocupa por dos cosas:

1. que cada vez me cuesta pillar más las cosas porque me hago viejo :-)

2. o que nadie excepto los que usan formato numérico usan RoR


En el forum inglés tampoco obtuve ninguna respuesta que me gustara,
simplemente tenía que alterar cada valor de cada campo numérico (float)
del europeo al inglés, para que RoR no se quejara al guardar el valor
numérico en la base de datos ...

Entiendo que haya que analizar bien la manera de entrar los valores,
pues uno nunca sabe qué es lo que el usuario entra pero seguro que tiene
que haber una manera más fácil ...

¿ alguien que me ilumine, por favor ?

muchas gracias!

r.
D48be99143e13e40d1c44a4da63a53f4?d=identicon&s=25 Mongeta 99 (raimon)
on 2009-05-04 18:26
Creo que no me he explicado bien ahora que lo estaba leyendo ...

Lo que me interesaría sería cambiar el formato/valor del valor entrado
por el usuario antes de que RoR lo asocie al objeto de ActiveRecord.

Si el campo fuerta string, no habría problema, pues el valor que el
usuario ha entrado es el mismo que está en RoR, pero en un campo
numérico float, RoR ya le cambia el valor cuando yo hago:

  @expedient=Expedient.new(params[:expedient])

Actualmente lo que hago es cambiar el valor de los campos que hay en el
array params, pero tengo que acordarme de hacerlo en Update, Create, y
alguno que otro sitio, y el principio de DRY se rompe, y hace la
aplicación más compleja.

Quería llevar estos cambios al Modelo, usar before_validation_on_create
pero cuando examino los valores, RoR ya los ha adaptado a su manera, y
el valor 1245,09 se ha transformado en 1245.00

¿ Cómo lo estás haciendo vosotros ?

¿ todos usáis formatos americanos ?

¿ se me escapa algo de I18n ?

gracias .......

salu2,

r.
7cc80e366962ecdea03eb1b150f6abf1?d=identicon&s=25 Fernando Val (aaromnido)
on 2009-05-04 18:29
(Received via mailing list)
De todos modos, la lista lleva unos días un poco parada. Yo tengo un
post al que aún no me ha respondiodo nadie, así que habrá que tener
paciencia...
(es el del "acts_a_tree")
Suerte, yo seguiré buscando guía y orientación... :-)

Ah, y no te preocupes, no eres el único que se hace viejo...   ;-)


Un saludo.

El día 4 de mayo de 2009 17:41, Raimon Fs
<ruby-forum-incoming@andreas-s.net>
escribió:>
>
> muchas gracias!
>
> r.
> --
> Posted via http://www.ruby-forum.com/.
> _______________________________________________
> Ror-es mailing list
> Ror-es@lists.simplelogica.net
> http://lists.simplelogica.net/mailman/listinfo/ror-es
>



--
Fernando Val
Web Designer
http://www.fernandoval.es
90ea347c45cdfbc1c5767dd6304d9c10?d=identicon&s=25 Borja Martín (Guest)
on 2009-05-04 18:32
(Received via mailing list)
Buenas,
puedes probar a usar el método <nombre_atributo>_before_type_cast para
acceder al atributo antes de que se haya la conversión de cara a
guardarlo
en la base de datos:

http://rails.noobkit.com/show/ruby/rails/rails-sta...

saludos

2009/5/4 Raimon Fs <ruby-forum-incoming@andreas-s.net>
7cc80e366962ecdea03eb1b150f6abf1?d=identicon&s=25 Fernando Val (aaromnido)
on 2009-05-04 18:34
(Received via mailing list)
Precisamente por eso te proponía descomponerlo, porque he leído en
varios sitios que el float tiene sus peligros con los redondeos. Creo
que lo comentan en el libro "Agile Web Development..." al crear la
aplicación Depot.

Pero si no puedes, habrá que buscar otra
solución.

El día 4 de mayo de 2009 18:29, Fernando <aaromnido@gmail.com>
escribió:>
>>
>> ¿ alguien que me ilumine, por favor ?
>>
>
>
>
> --
> Fernando Val
> Web Designer
> http://www.fernandoval.es
>



--
Fernando Val
Web Designer
http://www.fernandoval.es
D48be99143e13e40d1c44a4da63a53f4?d=identicon&s=25 Mongeta 99 (raimon)
on 2009-05-04 19:02
Borja Martín wrote:
> Buenas,
> puedes probar a usar el método <nombre_atributo>_before_type_cast para
> acceder al atributo antes de que se haya la conversión de cara a
> guardarlo
> en la base de datos:
>
> 
http://rails.noobkit.com/show/ruby/rails/rails-sta...

esto me ha ido perfecto !!!!

:-)

mira que leo, leo, leo, ... y siempre hay algo nuevo ...

gracias por la información ...

he creado en el modelo:

  def before_validation
     numbers_validations
  end

...
  def numbers_validations

    self.capital_total=
capital_total_before_type_cast.gsub(',','.').to_f if
capital_total_before_type_cast != nil
   ...
  end

y por las pruebas que he hecho, funciona a las mil maravillas ...

es una lástima que no coja directamente la información de la
configuración local, pero bueno, menos da una piedra ...

:-)

salu2 y gracias de nuevo ...

r.
348246701cfdb2130b842fd839751a18?d=identicon&s=25 Raul Murciano (raul)
on 2009-05-04 19:35
(Received via mailing list)
2009/5/4 Raimon Fs <ruby-forum-incoming@andreas-s.net>:
> Si el campo fuerta string, no habría problema, pues el valor que el
> usuario ha entrado es el mismo que está en RoR, pero en un campo
> numérico float

Si es para almacenar importes y vas a manejar céntimos te recomiendo
usar enteros y no floats para almacenarlos en la base de datos.
D48be99143e13e40d1c44a4da63a53f4?d=identicon&s=25 Mongeta 99 (raimon)
on 2009-05-04 20:00
Raul Murciano wrote:
> 2009/5/4 Raimon Fs <ruby-forum-incoming@andreas-s.net>:
>> Si el campo fuerta string, no habr�a problema, pues el valor que el
>> usuario ha entrado es el mismo que est� en RoR, pero en un campo
>> num�rico float
>
> Si es para almacenar importes y vas a manejar c�ntimos te recomiendo
> usar enteros y no floats para almacenarlos en la base de datos.

Uso BigDecimal (Numeric with precission)


salu2,

r.
C98e88f3e69340d27466baadb2b80b4c?d=identicon&s=25 Gunnar Wolf (Guest)
on 2009-05-04 23:51
(Received via mailing list)
Raimon Fs dijo [Mon, May 04, 2009 at 07:02:15PM +0200]:
>       capital_total_before_type_cast != nil
>    ...
>   end

Te sugiero ser un poco más precavido... Si tus usuarios te pueden
escribir, por ejemplo, tanto 1.234,56 como 1,234.56, ¿no deberías
poder reconocer a ambos? Bueno... Por simplicidad, permíteme asumir
que estás hablando de dinero, por lo que puedes tener hasta dos
posiciones después del punto (o coma) decimal:

def numbers_validations
  self.capital_total = capital_total_before_type_cast.
    gsub(/[,.](?=\d{3})/,  '').
    gsub(/[,.](\d+)$/) {|s| '.' + $1};
end

Saludos,

--
Gunnar Wolf - gwolf@gwolf.org - (+52-55)5623-0154 / 1451-2244
PGP key 1024D/8BB527AF 2001-10-23
Fingerprint: 0C79 D2D1 2C4E 9CE4 5973  F800 D80E F35A 8BB5 27AF
D48be99143e13e40d1c44a4da63a53f4?d=identicon&s=25 Mongeta 99 (raimon)
on 2009-05-05 08:12
Gunnar Wolf wrote:
> Raimon Fs dijo [Mon, May 04, 2009 at 07:02:15PM +0200]:
>>       capital_total_before_type_cast != nil
>>    ...
>>   end
>
> Te sugiero ser un poco más precavido... Si tus usuarios te pueden
> escribir, por ejemplo, tanto 1.234,56 como 1,234.56, ¿no deberías
> poder reconocer a ambos? Bueno... Por simplicidad, permíteme asumir
> que estás hablando de dinero, por lo que puedes tener hasta dos
> posiciones después del punto (o coma) decimal:
>
> def numbers_validations
>   self.capital_total = capital_total_before_type_cast.
>     gsub(/[,.](?=\d{3})/,  '').
>     gsub(/[,.](\d+)$/) {|s| '.' + $1};
> end

Hola,

Sí, tienes razón, pero para mi lo importante era donde poner el código
para interceptar los valores, y luego adaptarlo a las necesidades.

Quería hacerlo también teniendo en cuenta la configuración del locale
activado, pero al final, los usuarios escriben lo que les da la gana, o
sea que lo que tengo que hacer es adaptarlo a lo que la base de datos
quiere ...

gracias por el ejemplo!


salu2,

r.
0833bb96e21579feb636421aadb9d220?d=identicon&s=25 Rafa (Guest)
on 2009-05-05 09:27
(Received via mailing list)
Hola,

  Yo hace tiempo estuve buscando algo parecido, pero no encontré nada.
Además sabiendo como son los usuarios hay que controlar que no te puedan
escribir cualquier carácter no relacionado con un importe, por eso
también utilizaré funciones javascript para controlar la entrada de
datos.

  Salu2.
C98e88f3e69340d27466baadb2b80b4c?d=identicon&s=25 Gunnar Wolf (Guest)
on 2009-05-05 17:18
(Received via mailing list)
Raimon Fs dijo [Tue, May 05, 2009 at 08:12:42AM +0200]:
>
> Quería hacerlo también teniendo en cuenta la configuración del locale
> activado, pero al final, los usuarios escriben lo que les da la gana, o
> sea que lo que tengo que hacer es adaptarlo a lo que la base de datos
> quiere ...
>
> gracias por el ejemplo!

Jé, hasta me la pones más fácil - Si quieres descartar cualquier
caracter no numérico excepto por el último (si es que éste es un punto
o una coma):

capital_total_before_type_cast.gsub(/,/, '.').gsub(/[^\d.]/,
'').gsub(/\.(?=.+\.)/,'')

Tres expresiones regulares. La primera, pensando en los españoles que
hacen todo al revés ;-) convierte a todas las comas en puntos (para
tener un punto decimal como tu_deidad_favorita manda). La segunda,
descarta todos los caracteres excepto los dígitos numéricos y el
punto. Y como puedes tener más de un punto en tu cadena, la tercer
expresión elimina a cualquier punto que no sea el último de la cadena.

>> orig = '1 234,56_78.90,01'
=> "1 234,56_78.90,01"
>> limpio = orig.gsub(/,/, '.').gsub(/[^\d.]/, '').gsub(/\.(?=.+\.)/, '')
=> "1234567890.01"
>> limpio.to_f
=> 1234567890.01

Saludos,

--
Gunnar Wolf - gwolf@gwolf.org - (+52-55)5623-0154 / 1451-2244
PGP key 1024D/8BB527AF 2001-10-23
Fingerprint: 0C79 D2D1 2C4E 9CE4 5973  F800 D80E F35A 8BB5 27AF
D48be99143e13e40d1c44a4da63a53f4?d=identicon&s=25 Mongeta 99 (raimon)
on 2009-05-05 17:29
Gunnar Wolf wrote:
> Raimon Fs dijo [Tue, May 05, 2009 at 08:12:42AM +0200]:
>>
>> Quería hacerlo también teniendo en cuenta la configuración del locale
>> activado, pero al final, los usuarios escriben lo que les da la gana, o
>> sea que lo que tengo que hacer es adaptarlo a lo que la base de datos
>> quiere ...
>>
>> gracias por el ejemplo!
>
> Jé, hasta me la pones más fácil - Si quieres descartar cualquier
> caracter no numérico excepto por el último (si es que éste es un punto
> o una coma):
>
> capital_total_before_type_cast.gsub(/,/, '.').gsub(/[^\d.]/,
> '').gsub(/\.(?=.+\.)/,'')

gracias de nuevo ...

pero sigo con la mosca detrás de la oreja ...

¿ no hay ninguna manera de hacerlo mejor ?

estaría bien poder usar sólo
@dispo=Disposicion.new(params[:disposicion]) y que él solito hiciera el
resto en los campos BigDecimal, sin tener luego que hacer un nuevo cast
y poner el valor correcto en los atributos que RoR ha puesto mal, todo
esto antes de la validación ...

gracias de nuevo ...

r.
D48be99143e13e40d1c44a4da63a53f4?d=identicon&s=25 Mongeta 99 (raimon)
on 2009-05-05 17:44
Raimon Fs wrote:
> Gunnar Wolf wrote:
>> Raimon Fs dijo [Tue, May 05, 2009 at 08:12:42AM +0200]:
>>>
>>> Quería hacerlo también teniendo en cuenta la configuración del locale
>>> activado, pero al final, los usuarios escriben lo que les da la gana, o
>>> sea que lo que tengo que hacer es adaptarlo a lo que la base de datos
>>> quiere ...
>>>
>>> gracias por el ejemplo!
>>
>> Jé, hasta me la pones más fácil - Si quieres descartar cualquier
>> caracter no numérico excepto por el último (si es que éste es un punto
>> o una coma):
>>
>> capital_total_before_type_cast.gsub(/,/, '.').gsub(/[^\d.]/,
>> '').gsub(/\.(?=.+\.)/,'')

y para rizar el rizo ...

lo mismo pero en vez de un atributo, unos 20 ...

no vamos a escribir lo mismo para 20, alguna manera más fácil ?

en otros lenguajes usaría un Pointer y listo, pero aquí no lo tengo
claro aún, investigaré un poco a ver ...

self. capital_total =capital_total_before_type_cast.gsub(/,/,
'.').gsub(/[^\d.]/, '').gsub(/\.(?=.+\.)/,'')
self. capital_inicial= capital_inicial_before_type_cast.gsub(/,/,
'.').gsub(/[^\d.]/, '').gsub(/\.(?=.+\.)/,'')
...

salu2,

r.
C98e88f3e69340d27466baadb2b80b4c?d=identicon&s=25 Gunnar Wolf (Guest)
on 2009-05-06 03:50
(Received via mailing list)
Raimon Fs dijo [Tue, May 05, 2009 at 05:44:31PM +0200]:
> '.').gsub(/[^\d.]/, '').gsub(/\.(?=.+\.)/,'')
> self. capital_inicial= capital_inicial_before_type_cast.gsub(/,/,
> '.').gsub(/[^\d.]/, '').gsub(/\.(?=.+\.)/,'')
> ...

1- DRY. Si vas a repetir las regexes, mejor sácalas a un método.

  private
  def limpia_numero(entrada)
    entrada.gsub(/,/,  '.').gsub(/[^\d.]/, '').gsub(/\.(?=.+\.)/,'')
  end

2- Si son dos o tres atributos, no hay mayor problema, puedes ponelos
   explícitamente - ya queda más legible:

   self.capital_total = limpia_numero(capital_total_before_type_cast)
   self.capital_inicial =
limpia_numero(capital_inicial_before_type_cast)

   Sin embargo, puedes...

   %w(capital_total capital_inicial).each do |campo|
     self.send(campo) = limpia_numero(eval("#{campo}_before_type_cast"))
   end

Saludos,

--
Gunnar Wolf - gwolf@gwolf.org - (+52-55)5623-0154 / 1451-2244
PGP key 1024D/8BB527AF 2001-10-23
Fingerprint: 0C79 D2D1 2C4E 9CE4 5973  F800 D80E F35A 8BB5 27AF
D48be99143e13e40d1c44a4da63a53f4?d=identicon&s=25 Mongeta 99 (raimon)
on 2009-05-06 09:00
ok, gracias por la info!


salu2,

r.
This topic is locked and can not be replied to.