diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG index 26e0a7f9c2..d2cfdc6a4d 100644 --- a/activerecord/CHANGELOG +++ b/activerecord/CHANGELOG @@ -1,5 +1,7 @@ *SVN* +* Assigning nil to a composed_of aggregate also sets its immediate value to nil. #9843 [Chris Cruft] + * Ensure that mysql quotes table names with database names correctly. Closes #9911 [crayz] "foo.bar" => "`foo`.`bar`" diff --git a/activerecord/lib/active_record/aggregations.rb b/activerecord/lib/active_record/aggregations.rb index 8c3cdc3c11..8ee9d8368d 100644 --- a/activerecord/lib/active_record/aggregations.rb +++ b/activerecord/lib/active_record/aggregations.rb @@ -148,7 +148,7 @@ def reader_method(name, class_name, mapping, allow_nil) mapping = (Array === mapping.first ? mapping : [ mapping ]) allow_nil_condition = if allow_nil - mapping.collect { |pair| "!read_attribute(\"#{pair.first}\").nil?"}.join(" && ") + mapping.collect { |pair| "!read_attribute(\"#{pair.first}\").nil?"}.join(" || ") else "true" end @@ -169,10 +169,10 @@ def writer_method(name, class_name, mapping, allow_nil) if allow_nil module_eval <<-end_eval, __FILE__, __LINE__ def #{name}=(part) + @#{name} = part.freeze if part.nil? #{mapping.collect { |pair| "@attributes[\"#{pair.first}\"] = nil" }.join("\n")} else - @#{name} = part.freeze #{mapping.collect { |pair| "@attributes[\"#{pair.first}\"] = part.#{pair.last}" }.join("\n")} end end diff --git a/activerecord/test/aggregations_test.rb b/activerecord/test/aggregations_test.rb index 8cd4bfe481..89927e5044 100644 --- a/activerecord/test/aggregations_test.rb +++ b/activerecord/test/aggregations_test.rb @@ -92,4 +92,19 @@ def test_allow_nil_address_set_to_nil def test_nil_raises_error_when_allow_nil_is_false assert_raises(NoMethodError) { customers(:david).balance = nil } end + + def test_allow_nil_address_loaded_when_only_some_attributes_are_nil + customers(:zaphod).address_street = nil + customers(:zaphod).save + customers(:zaphod).reload + assert_kind_of Address, customers(:zaphod).address + assert customers(:zaphod).address.street.nil? + end + + def test_nil_assignment_results_in_nil + customers(:david).gps_location = GpsLocation.new('39x111') + assert_not_equal nil, customers(:david).gps_location + customers(:david).gps_location = nil + assert_equal nil, customers(:david).gps_location + end end