Hi List,

I've submitted another aggregations patch:
http://dev.rubyonrails.org/ticket/5336 (summary of patch contained
below)

Among other things, the patch alleviates 'odd' behaviour to do with
update_attributes described at
http://wiki.rubyonrails.com/rails/pages/UnderstandingAggregation

Cheers,
Ian

---
Summary: allow setting of one to one aggregated objects with simple
values (Strings, Integers, etc)

Currently, calling Customer.new(:balance => 100), customer.balance =
100, or customer.update_attributes(:balance => 100) will result in an
error like this:

NoMethodError: undefined method `amount' for 100:Fixnum
   (eval):3:in `balance='

This is inconvenient, as a lot of scaffolded controller code needs to
hand edited to first convert the attributes to value objects. It would
be nicer if rails could do this when it can.

In many cases, the current implementation of aggregations does not
give rise the above problem. It only occurs when (i) the aggregation
has the same name as a database column, and (ii) the aggregation
contains a mapping of a single attribute to that column.

(The reason for this behaviour is that, when (i) and (ii) aren't met,
the attr writer method will save the non value object data to the
attributes array, and the value object is constructed from that data
when it is later read)

To resolve this I've written a patch such that, when (i) and (ii) are
met, the attribute writer constructs a value object with the incoming
value if it is not an instance of the correct aggregated class.

I've written a couple of tests to prove this, and added a little extra
documentation.

FYI: running the test suite with the extra tests (but before the code
to fix it) produces the following errors (look in the patch to see the
tests that produce this)

 1) Error:
test_set_single_mapped_aggregation_without_value_object(AggregationsTest):
NoMethodError: undefined method `amount' for 123:Fixnum
   (eval):3:in `balance='
   ./test/aggregations_test.rb:27:in
`test_set_single_mapped_aggregation_without_value_object'

 2) Error:
test_update_attributes(AggregationsTest):
NoMethodError: undefined method `gps_location' for "38x-105":String
   (eval):6:in `gps_location='
   ./test/../lib/active_record/base.rb:1557:in `attributes='
   ./test/../lib/active_record/base.rb:1556:in `attributes='
   ./test/../lib/active_record/base.rb:1485:in `update_attributes'
   ./test/aggregations_test.rb:35:in `test_update_attributes'
_______________________________________________
Rails-core mailing list
Rails-core@lists.rubyonrails.org
http://lists.rubyonrails.org/mailman/listinfo/rails-core

Reply via email to