【问题标题】:How to get full price for money gem如何获得全价的金钱宝石
【发布时间】:2011-06-07 04:51:30
【问题描述】:

我正在使用money gem,我想知道我如何才能在一个字段中显示 23.45、10.00、0.32 之类的价格为 Dollar.cents? 我希望我的 cents 字段变为只是价格(金钱或美元和美分)。

这是我的代码:

我的模型与金钱 gem 组成:

class Price < ActiveRecord::Base
    attr_accessible :name, :date, :cents, :currency

    belongs_to :user

    validates :name,       :presence => true,
                           :length   => { :maximum => 50 }

    validates :currency,   :presence => true
    validates :cents,      :presence => true
    validates :date,       :presence => true

    default_scope :order => 'prices.created_at DESC'

    composed_of :price,
        :class_name => "Money",
        :mapping => [%w(cents cents), %w(currency currency_as_string)],
        :constructor => Proc.new { |cents, currency| Money.new(cents || 0, currency || Money.default_currency) },
        :converter => Proc.new { |value| value.respond_to?(:to_money) ? value.to_money : raise(ArgumentError, "Can't convert #{value.class} to Money") }
end

表格(为简洁起见,我剪掉了部分):

  <div class="field">
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </div>
  <div class="field">
    <%= f.label :date %><br />
    <%= f.date_select :date %>
  </div>
  <div class="field">
    <%= f.label :cents %><br />
    <%= f.text_field :cents %>
  </div>
  <><div class="field">
    <%= f.label :currency %><br />
    <%= f.select(:currency,major_currencies(Money::Currency::TABLE), 
    {:include_blank => 'Select a Currency'}) %>
  </div>

我的迁移或价格表:

class CreatePrices < ActiveRecord::Migration
  def self.up
    create_table :prices do |t|
      t.integer :user_id
      t.string :name
      t.date :date
      t.integer :cents, :default => 0
      t.string :currency

好像我错过了一个专栏或其他东西。它甚至假设是美分?不确定,所以我需要你的帮助。

感谢您抽出宝贵时间。

【问题讨论】:

  • 也许这会有所帮助:stackoverflow.com/questions/4798651/…
  • 只要看一下:您在 DB 中有美分,在视图中有货币(无论是哪个),所以 23.45 货币 == 2345 美分。
  • @apneadiving 我实际上遵循了你给我的公认答案让我开始,创造了这样的一切,但仍然遇到上述问题。
  • @santuxus 我也在想同样的事情,但我不知道如何配置它,所以我得到了全额。

标签: ruby-on-rails gem currency


【解决方案1】:

刚刚遇到了完全相同的问题,如果您不想像在选择的答案中那样更改数据库,只需查看 gem 的源代码,看看是否有任何可以解决的问题使用:

https://github.com/RubyMoney/money-rails/blob/master/lib/money-rails/helpers/action_view_extension.rb

在本模块中,您会注意到两件事:

  1. 名为 humanize_money 的方法
  2. 在该方法中,调用货币对象的方法格式

所以,只需调用 @my_money_object.format,然后....bam,您就可以将货币对象格式设置为带有美元的字符串,以及精度为 2 的美分金额。

例子:

@my_money_object = 20.to_money
@my_money_object.format

=>“$20.00”

这确实是正确的解决方案。您具体说您“只想要获得 45.23 美元这样的全价的方法”。现在,如果你想像这样将这个格式化的字符串放在你的数据库中,这取决于你,但我会考虑在需要的地方调用货币对象的格式方法。我需要在控制器中获取格式化的价格,并且显然无法访问 humanize_money 方法,除非我在视图中(没有尝试破解其他方法来执行此操作),所以我检查了源代码并发现这。如果这对您有任何帮助,请投票。

【讨论】:

    【解决方案2】:

    嗯,

    在您的数据库表中,您将美分保存为整数:

     t.integer :cents, :default => 0
    

    尝试将其更改为:

     t.decimal :cents, :default => 0
    

    【讨论】:

    • 现在这在一定程度上有效,我可以输入 23.45,但如果我输入 23.50,它会出现 23.5。
    • 23.50 与 23.5 完全一样——如果你想要最后的 0,我认为你必须在 ruby​​ 中格式化它
    • 你说得对,但这样人们就不会感到困惑,23.50 美元更有意义(呵呵,美分)。
    • 数据以数字形式来自数据库 - 您需要将其转换为字符串以用零填充 id。对于您的特定情况,如果它最后是 0 会更有意义 - 但没有办法知道默认放置多少个零是有意义的
    【解决方案3】:

    我下载了 gem 并测试了一些选项。按照https://github.com/RubyMoney/money 的示例,您可以这样做:

    money = Money.new(1000, "USD")
    money.cents     #=> 1000
    money.dollars   #=> 10.0
    

    所以在我看来,你的模型价格中应该有类似这种方法的东西:

    def value
      cents / 100.0
    end
    

    并在视图中使用它(或任何您需要货币价值的地方,而不是美分)。添加价格时,您是以美分计算的,因此要获得 12.34 的价格,您应该将其设置为 1234 美分。如果你想添加像 12.34 这样的价格,我想你应该在控制器中解析它(在创建/更新操作上)或在模型中使用过滤器 before_save 或类似的东西。只需将其乘以 100 即可在 DB 中保存为美分。

    编辑: 用于添加零以查看的辅助方法。

    def with_zeros(price)
      array = price.to_s.split('.')
      array[1] = array[1].ljust(2,'0')
      array.join('.')
    end
    

    【讨论】:

    • 我实际上不想用美分来做,我只是在关注这个网站上的教程和问题。我只想要在一个字段中获得 45.23 美元这样的全价的方法。
    • 在这种情况下,我认为 Tudor Constantin 提供了您正在寻找的解决方案......您可以添加一个辅助方法,在视图中添加您想要的零。 (我添加了上面的代码 - 它在逗号后返回带有数字的字符串)
    【解决方案4】:

    好的,我已经弄明白了,谢谢大家!

    这是我的新代码:

    数据库现在是 :price 而不是 :cents -

    create_table :prices do |t|
      t.integer :user_id
      t.string :name
      t.date :date
      t.integer :price, :default => 0
      t.string :currency
    

    表单区域:

      <div class="field">
        <%= f.label :price %><br />
        <%= f.text_field :price %>
      </div>
    

    新组成的:

    composed_of :price,
        :class_name  => "Money",
        :mapping     => [%w(price cents), %w(currency currency_as_string)],
        :constructor => Proc.new { |cents, currency| Money.new(cents || 0, currency || Money.default_currency) },
        :converter   => Proc.new { |value| value.respond_to?(:to_money) ? value.to_money : raise(ArgumentError, "Can't conver #{value.class} to Money") }
    

    我只需要让 composed_of 匹配 映射、数据库列和表单,并且由于某种奇怪的原因它开始完全工作。感谢大家的帮助,我学到了很多关于 ruby​​ 和 rails 的知识。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-15
      • 1970-01-01
      • 2020-08-02
      • 2015-07-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多