:composed_of conversion
====================
UPDATE: This plugin was added to Rails 2.0 (http://dev.rubyonrails.org/changeset/8003)
composed_of is handy, but it can also be a real pain. Primarily in that it makes it hard to use :composed_of fields in Rails forms. This rewrite of the Active Record :composed_of method allows you to specify a block to convert incoming parameters to the correct object type.
This has been most helpful when using the Money gem:
class Account < ActiveRecord::Base
composed_of :balance, :class_name => "Money", :mapping => %w(cents cents) do |amount|
amount.to_money
end
end
I Account#balance can now can have a form of type casting like any other attribute:
>> account = Account.new :balance => 100
>> account.balance
=> #
And now it can transparently be used in forms:
<%= text_field :account, :balance %>
This approach can even be used for more advanced aggregations:
class User < ActiveRecord::Base
composed_of :address, :class_name => "Address"
:mapping => [%w(street street), %w(city city), %w(state state), %w(zip zip)] do |addr|
Address.new(addr[:street], addr[:city], addr[:state], addr[:zip])
end
end
A user can now be created from a hash:
User.new(:address => {:street => "123 A Street", :city => "Somewhere", :state => "NO", :zip => 12345})
Additionally, the current version of composed_of builds a string and evals it to define the attribute accessors. It's dirty. This rewrite was submitted as a patch to the Rails trac (http://dev.rubyonrails.org/ticket/6322) but is yet to be accepted.