Rails ñ retorna casas decimais corretamente

1,272 views
Skip to first unread message

Francisco

unread,
Aug 14, 2012, 1:45:37 PM8/14/12
to rail...@googlegroups.com
Prezados,
Tenho alguns campos decimais ( no banco decimal(15,2) ) e quando eu tenho valores tipo 600.00 ele me retorna 600.0, mesmo no banco estando gravado 600.00, alguem sabe como corrigir isso? eu ja olhei no locale do i18n aparentemente todos os lugares q tratam de decimal estao setados para retornar duas casa.

Rails 3.2.6
Ruby 1.9.2

Grato por qualquer ajuda,

Francisco

Sidnei Pereira

unread,
Aug 14, 2012, 1:53:27 PM8/14/12
to rail...@googlegroups.com
number_to_currency(valor, :precision => 2)


--
Você recebeu essa mensagem porquê está inscrito no Google
Groups "rails-br".
Para enviar uma mensagem para o grupo, mande um email para rail...@googlegroups.com
Para se descadastrar, mande um e-mail para
rails-br+u...@googlegroups.com
Visite o grupo em http://groups.google.com/group/rails-br?hl=pt-BR
Leia nossa política de uso: http://goo.gl/YGgt7

Lukas Alexandre

unread,
Aug 14, 2012, 1:53:27 PM8/14/12
to rail...@googlegroups.com
Esse é o comportamento padrão da classe Float. Caso queira exibir esse número com as duas casas decimais você terá que manipulá-lo como string, manualmente ou com helper number_to_currency.


Lukas Alexandre
-- 
Ruby Developer

Francisco

unread,
Aug 14, 2012, 2:12:35 PM8/14/12
to rail...@googlegroups.com
Sidnei e Lukas, Boa!
Muito obrigado, mas ainda assim, isso resolve muito bem quando eu quero apenas exibir os valores, e quando eu preciso traze-los de volta para ediçao?

Tentei usar um  def valor number_to_currency(self.valor, precision => 2) end no model, mas ele dá um erro dizendo que nao pode encontrar o number to currency ou coisa parecida.

No rails 2 nao me lembro de ter deparado com esse problema nenhuma vez.


Abs

Sidnei Pereira

unread,
Aug 14, 2012, 2:23:32 PM8/14/12
to rail...@googlegroups.com
Então caso seja valor cheio ele retorna sem a virgula, caso seja valor com decimal ele retorna com as decimais. Mas para editar com as casas decimais em valor cheio não tenho uma solução, estou com problemas também para usar virgula na hora de criar um novo valor, ele só funciona as decimais se for com ponto.

Francisco

unread,
Aug 14, 2012, 2:36:29 PM8/14/12
to rail...@googlegroups.com
Eu nao tenho problema que ele retorne com ponto ao invés de virgula, mas eu preciso que ele retorne as 2 casas decimais. Essa é a minha dificuldade, e pelo que eu entendi, o helper number_to_currency só funciona para views, e nessa caso eu precisaria de uma soluçao pra tratar esse valor no model, antes que ele chegue na view, para evitar que vá o valor errado para a textbox, como esta acontecendo.

De qualquer jeito, valeu! =)

Sidnei Pereira

unread,
Aug 14, 2012, 2:39:50 PM8/14/12
to rail...@googlegroups.com
Tenta dar um include na model para usar ele, acho que funciona.
include ApplicationHelper

Francisco

unread,
Aug 14, 2012, 2:52:01 PM8/14/12
to rail...@googlegroups.com
  def valor_unitario
    number_to_currency(self.valor_unitario, :precision => 2)
  end


continua voltando errado do mesmo jeito =/

thiagocifani

unread,
Aug 14, 2012, 3:23:52 PM8/14/12
to rail...@googlegroups.com
Vc tem que primeiramente especificar na migration  a precision como nesse post : http://millarian.com/programming/ruby-on-rails/precision-and-scale-for-ruby-on-rails-migrations/

Mas vc pode formatar dessa forma tb
sprintf('%.2f', self)

Abraço 


Sent from my iPhone

Francisco

unread,
Aug 14, 2012, 3:35:05 PM8/14/12
to rail...@googlegroups.com
Valeu Thiago!
Esta especificado na migrate o formato, tanto que no banco o valor é gravado da forma certa, é na hora do retorno que o rails bagunça todo o coreto.
Vou testar a forma q sugeriu!
abs

Vinicius Silva

unread,
Jun 6, 2013, 6:45:20 PM6/6/13
to rail...@googlegroups.com
Impressiona a falta de resposta.

Gostaria de saber o que foi feito e se foi feito qual o resultado.

Estou com esse problema, cadastro um preço do produto R$50.00 e quando vou exibir mostra apenas 50.0
E ai, o que fazer para mostrar sempre e em todos os campos quando usar float?

Everaldo Gomes

unread,
Jun 6, 2013, 6:49:15 PM6/6/13
to rail...@googlegroups.com
@Vinicius, não use float. Use decimal.

O que você usou?


2013/6/6 Vinicius Silva <vinip...@gmail.com>
--
--
Você recebeu essa mensagem porquê está inscrito no Google
Groups "rails-br".
Para enviar uma mensagem para o grupo, mande um email para rail...@googlegroups.com
Para se descadastrar, mande um e-mail para
rails-br+u...@googlegroups.com
Visite o grupo em http://groups.google.com/group/rails-br?hl=pt-BR
Leia nossa política de uso: http://goo.gl/YGgt7
 
---
Você está recebendo esta mensagem porque se inscreveu no grupo "rails-br" dos Grupos do Google.
Para cancelar a inscrição neste grupo e parar de receber seus e-mails, envie um e-mail para rails-br+u...@googlegroups.com.
Para obter mais opções, acesse https://groups.google.com/groups/opt_out.
 
 

Vinicius Silva

unread,
Jun 6, 2013, 6:59:53 PM6/6/13
to rail...@googlegroups.com
Usei float.

Vinicius Silva

unread,
Jun 6, 2013, 7:01:40 PM6/6/13
to rail...@googlegroups.com
Bom, onde eu vi float no valor é no schema no db.

Devo fazer alterar os campos que contém preco :float para

preco :decimal ??


Em terça-feira, 14 de agosto de 2012 14h45min37s UTC-3, Francisco escreveu:

Everaldo Gomes

unread,
Jun 6, 2013, 7:06:40 PM6/6/13
to rail...@googlegroups.com
change_column ou remova e adicione de novo.




2013/6/6 Vinicius Silva <vinip...@gmail.com>

Vinicius Silva

unread,
Jun 6, 2013, 7:12:11 PM6/6/13
to rail...@googlegroups.com
Estou no início do projeto, executei o rake db:rollback STEP=14

Esquema vazio, e agora vou alterar os campos, em tudo que for relacionado a preço, exemplo, preco_venda, preco_compra, desconto, alterarei para decimal.

Já reporto o resultado.

Everaldo Gomes

unread,
Jun 6, 2013, 7:17:05 PM6/6/13
to rail...@googlegroups.com
Isso aí, altera pra decimal e não terá problemas em relação à precisão.





2013/6/6 Vinicius Silva <vinip...@gmail.com>

Vinicius Silva

unread,
Jun 6, 2013, 7:47:28 PM6/6/13
to rail...@googlegroups.com
Mesmo colocando como decimal continua sem exibir todas as casas.

Eu só alterei os campos no migrate e depois executei o rake db:migrate. Lá no schema já exibe t.decimal "valor_item"

Devo alterar mais em algum lugar? Existe um modo de exibir os campos correto? Se for o caso posso cadastrar o preço dos produto tudo quebradinho rsrs... mas essa não seria uma solução legal. =P

Se eu colocar 49.00 exibe 49.0
Se eu colocar 49.10 vai exibir 49.1
mas se colocar 49.11 ai sim exibe 49.11

O que posso estar fazendo para acertar?

Desde já grato.

Mairon Brasil

unread,
Jun 6, 2013, 8:07:05 PM6/6/13
to rail...@googlegroups.com
cada da uma olhadinha na gem "delocalize"

Alexandre Viegas

unread,
Jun 6, 2013, 8:21:05 PM6/6/13
to rail...@googlegroups.com
cara uma vez eu fis assim em um projeto

<%=f.text_field :valor, :value => (to_real(@item.valor) unless @item.new_record?), :class => 'moeda' %>

sendo que esse to_real era um método que eu tinha colocado no ApplicationHelper



def to_real(valor)
    number_to_currency(valor)
end


e esse :class => 'moeda', tem um jquery associado, q eu "peguei emprestado" do site do banco do brasil :D é meio grandinho mas no tempo funcionou legal no projeto


$(document).ready(function() {
  
   function filtraCampoValor(valor){
    var s = "";
    var cp = "";
    vr = valor;
    tam = vr.length;
    for (i = 0; i < tam ; i++) {
      if (vr.substring(i,i + 1) >= "0" && vr.substring(i,i + 1) <= "9"){
        s = s + vr.substring(i,i + 1);}
    }
    valor = s;
    return cp = valor;
  }

  $(".moeda").css('text-align', 'right').val(function(){
    $(this).val(filtraCampoValor($(this).val()));
    vr = $(this).val();
    tam = vr.length;

    if ( tam == 1 ){
      return '0,0' + vr; }
    if ( tam == 2 ){
      return '0,' + vr; }
    if ( (tam > 2) && (tam <= 5) ){
      return vr.substr( 0, tam - 2 ) + ',' + vr.substr( tam - 2, tam ); }
    if ( (tam >= 6) && (tam <= 8) ){
      return vr.substr( 0, tam - 5 ) + '.' + vr.substr( tam - 5, 3 ) + ',' + vr.substr( tam - 2, tam ); }
    if ( (tam >= 9) && (tam <= 11) ){
      return vr.substr( 0, tam - 8 ) + '.' + vr.substr( tam - 8, 3 ) + '.' + vr.substr( tam - 5, 3 ) + ',' + vr.substr( tam - 2, tam ); }
    if ( (tam >= 12) && (tam <= 14) ){
      return vr.substr( 0, tam - 11 ) + '.' + vr.substr( tam - 11, 3 ) + '.' + vr.substr( tam - 8, 3 ) + '.' + vr.substr( tam - 5, 3 ) + ',' + vr.substr( tam - 2, tam ); }
    if ( (tam >= 15) && (tam <= 18) ){
      return vr.substr( 0, tam - 14 ) + '.' + vr.substr( tam - 14, 3 ) + '.' + vr.substr( tam - 11, 3 ) + '.' + vr.substr( tam - 8, 3 ) + '.' + vr.substr( tam - 5, 3 ) + ',' + vr.substr( tam - 2, tam );}
  });
  $(".moeda").keyup(function () {
    $(this).val(filtraCampoValor($(this).val())); 
    vr = $(this).val();
    tam = vr.length;

    if ( tam <= 2 ){ 
      $(this).val(vr); }
    if ( (tam > 2) && (tam <= 5) ){
      $(this).val(vr.substr( 0, tam - 2 ) + ',' + vr.substr( tam - 2, tam )); }
    if ( (tam >= 6) && (tam <= 8) ){
      $(this).val(vr.substr( 0, tam - 5 ) + '.' + vr.substr( tam - 5, 3 ) + ',' + vr.substr( tam - 2, tam )); }
    if ( (tam >= 9) && (tam <= 11) ){
      $(this).val(vr.substr( 0, tam - 8 ) + '.' + vr.substr( tam - 8, 3 ) + '.' + vr.substr( tam - 5, 3 ) + ',' + vr.substr( tam - 2, tam )); }
    if ( (tam >= 12) && (tam <= 14) ){
      $(this).val(vr.substr( 0, tam - 11 ) + '.' + vr.substr( tam - 11, 3 ) + '.' + vr.substr( tam - 8, 3 ) + '.' + vr.substr( tam - 5, 3 ) + ',' + vr.substr( tam - 2, tam )); }
    if ( (tam >= 15) && (tam <= 18) ){
      $(this).val(vr.substr( 0, tam - 14 ) + '.' + vr.substr( tam - 14, 3 ) + '.' + vr.substr( tam - 11, 3 ) + '.' + vr.substr( tam - 8, 3 ) + '.' + vr.substr( tam - 5, 3 ) + ',' + vr.substr( tam - 2, tam ));}
  });
});





vê se te ajuda
Até mais,
Alexandre Viegas

Vinicius Silva

unread,
Jun 6, 2013, 8:43:27 PM6/6/13
to rail...@googlegroups.com
Pensei que com o Brazilian Rails (brNumeros/brDinheiro) e mais o atributo decimal resolveria o problema.
Cara não tem nada de fácil em desenvolvimento web como diz uns cursos por ai. Sempre que se quer resolver algo, instala isso, instala aquilo, para resolver um problema simples.

Triste e tenso.

Estava lendo antes, quando ainda estava usando float. .round(2) -- imaginei simples assim, blz! Que seria esse o comando que eu colocaria nos campos que recebem o valor para exibir corretamente.
Hunf... não mudou nada.

Deixa pra lá, o jeito mesmo é não usar números redondos. 1,99 ao invés de 2.00 que ficará 2.0

Aqui no Brasil as coisas são assim mesmo, então não estaria fugindo do padrão.

Valeu pessoal. Espero que pelo menos nos cálculos isso não me traga nenhum prejuízo.



Em terça-feira, 14 de agosto de 2012 14h45min37s UTC-3, Francisco escreveu:

Everaldo Gomes

unread,
Jun 6, 2013, 8:47:12 PM6/6/13
to rail...@googlegroups.com
@Vinicius, ele não está exibindo na tela, mas não quer dizer que não está armazenando certo.

Olha, não é certo usar float para moedas etc. O certo é decimal mesmo.

E já te mandaram a resposta, tem que usar o number_to_currency.

Não é difícil....difícil é ficar escrevendo o mesmo código zilhões de vezes...

Tem que estudar, não tem jeito. Mas veja pelo lado bom: já que poucos conseguem fazer, há escassez...então você pode cobrar mais.

Até!

[]s




2013/6/6 Vinicius Silva <vinip...@gmail.com>

Vinicius Silva

unread,
Jun 6, 2013, 9:33:36 PM6/6/13
to rail...@googlegroups.com

Galera vou postar os passos que fiz como teste. No meu _form produto alterei:

<div class="control-group">

    <%= f.label :preco_compra, "Preço da compra: R$", :class => "control-label" %>

    <div class="controls">

      <%= f.text_field :preco_compra,

       :class => "moeda",

       :value => (to_real(@produto.preco_compra) unless @produto.new_record?)  %>

    </div>

  </div>

 

No meu app>helpers>application_helper fiz:

def to_real(valor)

                number_to_currency(valor)

end

 

E no meu app>assets>javascript>application.js  - copiei e colei o código inteiro emprestado do amigo Alexandre Veigas, que orientou para essa solução.


E agora? Tenho o index.html.erb e o show.html.erb - Olhando o código não foi muito diferente do que fiz para a data. Criei um helper string_to_date, uma mascara em js e

nas telinhas eu ponho dt_nascimento.strftime("%d/%m/%Y") e pronto, lá se exibe a data correta/ editar.. Tudo certinho.


O que devo colocar em preco_compra.ALGUMA COISA

Como o nosso amigo falou, não exibir correto, não significa que esta armazenando errado. Então o meu problema é só na hora de exibir.

Fiz errado, esqueci de algo.

Toda ajuda é bem vinda.

Luiz Augusto B. Florentino Filho

unread,
Jun 6, 2013, 9:48:42 PM6/6/13
to rail...@googlegroups.com
Na realidade, o ideal é usar Integer para valores monetários. Existe um artigo de Fowler alando sobre isso.

De qualquer forma, qual o problema de exibir 2,1 ao invés de 2,10 num campo?

Douglas Rossignolli

unread,
Jun 6, 2013, 9:57:15 PM6/6/13
to rail...@googlegroups.com
desculpa gente, mas vcs estão fazendo tempestade em copo d'gua

fiz esse helper aqui na minha app


var Helpers = (function() {
var Helper = function() { }

// transforma a float into a currency format
Helper.currency_format = function (value) {
if (value == "0") return "R$ 0,00";

if (typeof value == "string") value = parseFloat(value);
var element = $("<p>");

element.text(value.toFixed(2));
element.priceFormat(); // <<<<< http://jquerypriceformat.com/

return element.text();
};

// transforma a float into a currency format
Helper.currency_to_float = function (value) {
value = value.replace("R$ ", "");

for(var f in value) {
     if(value[f] == "."){
     value = value.replace(".", "");
      }

      if(value[f] == ","){
       value = value.replace(",", ".");
      }
    }
    value = parseFloat(value);
    return value;

};

Atenciosamente,
Douglas Rossignolli

Everaldo Gomes

unread,
Jun 6, 2013, 10:18:10 PM6/6/13
to rail...@googlegroups.com
Se o Fowler disse integer, então que seja integer. :)

O certo seria ter uma Money class, né?

Um Value Object....


@Vinicius, não entendi seu código...difícil de ler código em preto-e-branco.


Não tenho código à mão pra te mostrar...mas é bem fácil.

Eu também costumo usar localização, ou internacionalização (nunca lembro a diferença) - para mostrar a vírgula ao invés do ponto decimal e o símbolo em reais. Basta baixar o arquivo i18n do Rails....





2013/6/6 Douglas Rossignolli <douglas.r...@gmail.com>

Jefferson Venerando

unread,
Jun 7, 2013, 7:19:24 AM6/7/13
to rail...@googlegroups.com
No sistema que eu trabalho atualmente tem uma folha de pagamentos, e todos os valores do sistema estão em Float.

Dá vontade chorar quando vejo o resultado final.

São arquivos que precisam ir pra bancos, que preciso enviar pro governo anualmente, e a falta de precisão é horrível.

Estou reescrevendo e usando integer pra valores, com ajuda da money-rails (https://github.com/RubyMoney/money-rails) e não tive problemas.

Ah, como uma dica, já que eu preciso gravar valores bem altos, dá pau no campo int, então eu gravo como big int.

No migration ficaria assim:
't.column :vencimento_base_centavos, :bigint'

Luiz Augusto B. Florentino Filho

unread,
Jun 7, 2013, 7:21:52 AM6/7/13
to Rails Group

Vinicius Silva

unread,
Jun 8, 2013, 4:48:27 PM6/8/13
to rail...@googlegroups.com
Galera consegui resolver lendo uma apostila. No meu caso resolvi da seguinte maneira:
Criei um método no app>>helpers>>apllication_helper.rb

def valor_formatado(number)
        number_to_currency(number, :unit => "R$", :separator => ",", :delimiter => ".")
    end

E em cada view(index/show) onde exibe o valor fiz o seguinte:

<%= valor_formatado(f.preco_compra) %>

Antes se colocássemos o valor 1,90 ele iria exibir 1.9 e agora vai exibir R$1,90 corretamente.

Espero ter ajudado.

Everaldo Gomes

unread,
Jun 8, 2013, 4:52:19 PM6/8/13
to rail...@googlegroups.com
Legal, que funcionou. Viu que não era tão difícil?

E muito bom da sua parte compartilhar a solução, eis o espírito da lista. :)


2013/6/8 Vinicius Silva <vinip...@gmail.com>

Anchieta Junior

unread,
Sep 22, 2015, 3:55:37 PM9/22/15
to rails-br
Olá Jefferson, você ainda usa essa gem pra manusear campos monetários ?
Se sim, poderia mostrar como você configura  o money.rb pra aceitar campos decimais com vírgula?

Grato.
Reply all
Reply to author
Forward
0 new messages