如何获得全价钱宝石

时间:2011-06-07 04:51:30

标签: ruby-on-rails gem currency

我正在使用money gem,我想知道我如何能够像23.45,10.00,0.32这样的价格在一个字段中显示为dollar.cents?我想要我的美分字段变得只是价格(金钱或美元和美分)。

这是我的代码:

我的模型有金钱宝石撰写:

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

似乎我错过了一个专栏或其他什么东西。甚至假设只是美分?不确定所以我需要你的帮助。

感谢您抽出宝贵时间。

4 个答案:

答案 0 :(得分:4)

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

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

在本单元中,您将注意到两件事:

  1. 名为humanize_money的方法
  2. 在该方法中,调用货币对象上的方法格式
  3. 所以,只需调用 @ my_money_object.format ,然后.... bam,你的钱对象格式为美元字符串,精度为2美分。 / p>

    示例:

    @my_money_object = 20.to_money
    @my_money_object.format
    

    =&GT; “$ 20.00”

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

答案 1 :(得分:1)

那么,

在你的数据库表中,你将美分作为整数:

 t.integer :cents, :default => 0

尝试将其更改为:

 t.decimal :cents, :default => 0

答案 2 :(得分:1)

我下载了gem并测试了一些选项。按照https://github.com/RubyMoney/money中的示例,您可以执行以下操作:

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

所以在我看来你应该在你的模型中使用这种方法Price:

def value
  cents / 100.0
end

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

编辑: 用于向视图添加零的辅助方法。

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

答案 3 :(得分:0)

好吧,我能够弄清楚,谢谢大家!

这是我的新代码:

数据库现在是:价格而不是:美分 -

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>

new composed_of:

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 映射,数据库列和表单匹配,并且出于某些奇怪的原因它完全开始工作。谢谢大家的帮助,我学到了很多关于红宝石和铁轨的知识。