Search code examples
ruby-on-railsformsrubygemscurrencyformbuilder

Rails money gem and form builder


I'm having an issue with the forms and the money gem.

This is my problem:

  1. I create a record which has an "amount" field (mapped to money object). Let's say I enter 10 (dollars).
  2. The money gem converts it to 1000 (cents)
  3. I edit the same record and the form pre-populates the amount field as 1000
  4. If I save the record without changing anything, it will convert the 1000 (dollars) to 100000 (cents)

How do I make it display the pre-populated amount in dollars instead of cents?

Edit:

I tried editing the _form.html like this:

= f.text_field(:amount, :to_money)

and I get this error:

undefined method `merge' for :to_money:Symbol

Solution

  • Given a migration as follows:

    class CreateItems < ActiveRecord::Migration
      def self.up
        create_table :items do |t|
          t.integer :cents
          t.string :currency
          t.timestamps
        end
      end
    
      def self.down
        drop_table :items
      end
    end
    

    And a model as follows:

    class Item < ActiveRecord::Base
      composed_of :amount,
        :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 conver #{value.class} to Money") }
    end
    

    Then this form code should work perfectly (I just tested under Rails 3.0.3), properly displaying and saving the dollar amount every time you save/edit. (This is using the default scaffold update/create methods).

    <%= form_for(@item) do |f| %>
      <div class="field">
        <%= f.label :amount %><br />
        <%= f.text_field :amount %>
      </div>
      <div class="actions">
        <%= f.submit %>
      </div>
    <% end %>