РЕДАКТИРОВАТЬ: Добавлен бонус в конце ответа
Ну, ваш вопрос был мне интересен, поэтому я решил попробовать себя.
Это работает правильно:
1) Миграция продукта:
create_table :products do |t|
t.string :name
t.integer :cents, :default => 0
t.string :currency
t.timestamps
end
2) Модель товара
class Product < ActiveRecord::Base
attr_accessible :name, :cents, :currency
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
3) Форма:
<%= form_for(@product) do |f| %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :cents %><br />
<%= f.text_field :cents %>
</div>
<div class="field">
<%= f.label :currency %><br />
<%= f.select(:currency,all_currencies(Money::Currency::TABLE), {:include_blank => 'Select a Currency'}) %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
4) Продукция Helper (ручная работа):
module ProductsHelper
def major_currencies(hash)
hash.inject([]) do |array, (id, attributes)|
priority = attributes[:priority]
if priority && priority < 10
array ||= []
array << [attributes[:name], attributes[:iso_code]]
end
array
end
end
def all_currencies(hash)
hash.inject([]) do |array, (id, attributes)|
array ||= []
array << [attributes[:name], attributes[:iso_code]]
array
end
end
end
БОНУС:
Если вы хотите добавить курсы обмена валют:
1) Ваш гемфайл
gem 'json' #important, was not set as a dependency, so I add it manually
gem 'google_currency'
2) Инициализатор
создайте файл money.rb в вашей папке инициализаторов и поместите его внутрь:
require 'money'
require 'money/bank/google_currency'
Money.default_bank = Money::Bank::GoogleCurrency.new
перезагрузите сервер
3) Играй!
Где бы вы ни находились, вы можете обменять деньги.
Product.first.price.exchange_to('USD')
Дисплей с хорошим рендерингом:
Product.first.price.format(:symbol => true)