diff options
Diffstat (limited to 'activerecord/lib/active_record/aggregations.rb')
-rw-r--r-- | activerecord/lib/active_record/aggregations.rb | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/activerecord/lib/active_record/aggregations.rb b/activerecord/lib/active_record/aggregations.rb index e0392c5a48..3ae7030caa 100644 --- a/activerecord/lib/active_record/aggregations.rb +++ b/activerecord/lib/active_record/aggregations.rb @@ -166,6 +166,7 @@ module ActiveRecord # finds all customers with +balance_amount+ equal to 20 and +balance_currency+ equal to "USD": # # Customer.where(:balance => Money.new(20, "USD")).all + # module ClassMethods # Adds reader and writer methods for manipulating a value object: # <tt>composed_of :address</tt> adds <tt>address</tt> and <tt>address=(new_address)</tt> methods. @@ -192,7 +193,8 @@ module ActiveRecord # * <tt>:converter</tt> - A symbol specifying the name of a class method of <tt>:class_name</tt> # or a Proc that is called when a new value is assigned to the value object. The converter is # passed the single value that is used in the assignment and is only called if the new value is - # not an instance of <tt>:class_name</tt>. + # not an instance of <tt>:class_name</tt>. If <tt>:allow_nil</tt> is set to true, the converter + # can return nil to skip the assignment. # # Option examples: # composed_of :temperature, :mapping => %w(reading celsius) @@ -206,6 +208,7 @@ module ActiveRecord # :mapping => %w(ip to_i), # :constructor => Proc.new { |ip| IPAddr.new(ip, Socket::AF_INET) }, # :converter => Proc.new { |ip| ip.is_a?(Integer) ? IPAddr.new(ip, Socket::AF_INET) : IPAddr.new(ip.to_s) } + # def composed_of(part_id, options = {}) options.assert_valid_keys(:class_name, :mapping, :allow_nil, :constructor, :converter) @@ -239,16 +242,15 @@ module ActiveRecord def writer_method(name, class_name, mapping, allow_nil, converter) define_method("#{name}=") do |part| + klass = class_name.constantize + unless part.is_a?(klass) || converter.nil? || part.nil? + part = converter.respond_to?(:call) ? converter.call(part) : klass.send(converter, part) + end + if part.nil? && allow_nil mapping.each { |pair| self[pair.first] = nil } @aggregation_cache[name] = nil else - unless part.is_a?(class_name.constantize) || converter.nil? - part = converter.respond_to?(:call) ? - converter.call(part) : - class_name.constantize.send(converter, part) - end - mapping.each { |pair| self[pair.first] = part.send(pair.last) } @aggregation_cache[name] = part.freeze end |