【问题标题】:Ruby on Rails - Currency : commas causing an issueRuby on Rails - 货币:逗号导致问题
【发布时间】:2011-01-09 05:53:33
【问题描述】:

看着 SO,我发现使用 RoR 货币的首选方法是使用小数(8,2)并使用 number_to_currency() 输出它们;

我可以将我的号码从数据库中取出,但我在将它们输入时遇到了问题。

在我的更新操作中,我有以下行:

if @non_labor_expense.update_attributes(params[:non_labor_expense]) 
puts YAML::dump(params) 

参数转储显示正确的值。 xx,yyy.zz ,但存储在数据库中的只有 xx.00

我需要做什么才能考虑到可能存在逗号并且用户可能无法输入 .zz(美分)。一些正则表达式和逗号?如果它是 .2 与 .20 ,你将如何处理小数。

必须有一个内置的或至少一个更好的方法。

我的迁移(我不知道这是否有帮助):

class ChangeExpenseToDec < ActiveRecord::Migration
    def self.up
       change_column :non_labor_expenses, :amount, :decimal, :precision => 8, :scale => 2
    end

    def self.down
          change_column :non_labor_expenses, :amount, :integer
    end
end

【问题讨论】:

  • .2 和 .20 是同一个数字,所以存储方式无关紧要,重要的是显示方式。
  • 对。第一个问题是我在逗号后丢失了数据。您是说一旦我解决了这个问题,.2 和 .20 将自行解决它在数据库中的存储方式?
  • 看我的回答;基本上,您将数据库中的数字存储为直接(未格式化)十进制数,然后在需要显示时根据需要对其进行格式化。

标签: ruby-on-rails decimal numbers currency


【解决方案1】:

查看 delocalize gem:

http://github.com/clemens/delocalize

【讨论】:

    【解决方案2】:

    在这里您可以找到一个代码 sn-p,它可以使任何十进制列接受以逗号作为小数分隔符的值:

    http://gem-session.com/2010/03/how-to-use-the-comma-as-decimal-separator-in-rails-activerecord-columns-and-text-fields

    【讨论】:

    【解决方案3】:

    我尝试了 Daniel 的 before_validation 想法,但我无法让它发挥作用。似乎当我到达 before_validation 时,输入已经被转换了。我采用的解决方案是覆盖列的方法,并在那里去掉逗号:

    def profit=(num)
      num.gsub!(',','') if num.is_a?(String)
      self[:profit] = num
    end
    

    【讨论】:

    • 有效,但如果您打算将 , 转换为 .应用中的多个输入。
    • 这行得通,您也可以在 before_validation 回调中挂钩 attribute_before_type_cast,例如self.profit = profit_before_type_cast.to_s.gsub(/,/,'')
    • 这是一个救命的答案:)
    【解决方案4】:

    这可能取决于您使用的 DBMS,但据我所知,十进制字段不接受逗号(至少不能作为分隔符;可能有一种方法可以让数据库接受逗号作为小数点而不是句号)。您需要做的是从您的号码中删除逗号(可能是在before_savebefore_validation 过滤器中),然后当您显示号码时,重新添加逗号。

    before_validation :strip_commas_from_non_labor_expense
    
    def strip_commas_from_non_labor_expense
      self.non_labor_expense = self.non_labor_expense.to_s.gsub(/,/, '').to_f
    end
    

    然后使用number_to_currency,当您想要显示格式为逗号分隔组和两位小数的费用金额时,如您所述:

    <%
      non_labor_expense = ... # get value from your model
      puts number_to_currency(non_labor_expense, :precision => 2, :separator => ',')
    %>
    

    【讨论】:

    • 我尝试了你的 before_validation 和模型中的函数,我输入了 YAML::dump(self.amount) 但金额已经被截断。我收到以下错误:私有方法“gsub!”当我将您的代码更改为:self.amount.gsub!('/,/', '') 有什么想法吗?
    • 如果我做 self.amount.to_s.gsub!('/,/', '') 然后 gsub!有效,但是在我拨打电话之前进行转储,看起来好像该值已被截断。有什么想法吗?
    • 对不起,我更新了我的答案。正则表达式周围不需要引号(我今天处于 PHP 模式,呵呵),应该使用 gsub 而不是 gsub!,因为如果没有进行替换,后者会用 nil 替换字符串。另外,我在末尾添加了to_f 以将其放回浮动中。
    • 我经历过这种小数的切割。
    猜你喜欢
    • 2019-07-11
    • 1970-01-01
    • 1970-01-01
    • 2017-10-26
    • 1970-01-01
    • 1970-01-01
    • 2011-03-05
    • 2017-05-07
    • 1970-01-01
    相关资源
    最近更新 更多