aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activerecord/CHANGELOG14
-rwxr-xr-xactiverecord/lib/active_record/associations.rb3
-rw-r--r--activerecord/lib/active_record/associations/association_proxy.rb4
-rw-r--r--activerecord/lib/active_record/associations/has_one_association.rb9
-rwxr-xr-xactiverecord/test/associations_test.rb3
5 files changed, 29 insertions, 4 deletions
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG
index d17ff99f54..63daed1433 100644
--- a/activerecord/CHANGELOG
+++ b/activerecord/CHANGELOG
@@ -1,5 +1,19 @@
*SVN*
+* Added destruction of dependent objects in has_one associations when a new assignment happens #742 [mindel]. Example:
+
+ class Account < ActiveRecord::Base
+ has_one :credit_card, :dependent => true
+ end
+ class CreditCard < ActiveRecord::Base
+ belongs_to :account
+ end
+
+ account.credit_card # => returns existing credit card, lets say id = 12
+ account.credit_card = CreditCard.create("number" => "123")
+ account.save # => CC with id = 12 is destroyed
+
+
* Added validates_numericality_of #716 [skanthak/c.r.mcgrath]. Docuemntation:
Validates whether the value of the specified attribute is numeric by trying to convert it to
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index 381f3e4931..229cfb5cfa 100755
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -270,7 +270,8 @@ module ActiveRecord
# sql fragment, such as "rank = 5".
# * <tt>:order</tt> - specify the order from which the associated object will be picked at the top. Specified as
# an "ORDER BY" sql fragment, such as "last_name, first_name DESC"
- # * <tt>:dependent</tt> - if set to true the associated object is destroyed alongside this object
+ # * <tt>:dependent</tt> - if set to true, the associated object is destroyed when this object is. It's also destroyed if another
+ # association is assigned.
# * <tt>:foreign_key</tt> - specify the foreign key used for the association. By default this is guessed to be the name
# of this class in lower-case and "_id" suffixed. So a +Person+ class that makes a has_one association will use "person_id"
# as the default foreign_key.
diff --git a/activerecord/lib/active_record/associations/association_proxy.rb b/activerecord/lib/active_record/associations/association_proxy.rb
index 009e2ec4c2..91da7dec4d 100644
--- a/activerecord/lib/active_record/associations/association_proxy.rb
+++ b/activerecord/lib/active_record/associations/association_proxy.rb
@@ -34,6 +34,10 @@ module ActiveRecord
end
protected
+ def dependent?
+ @options[:dependent] || false
+ end
+
def quoted_record_ids(records)
records.map { |record| record.quoted_id }.join(',')
end
diff --git a/activerecord/lib/active_record/associations/has_one_association.rb b/activerecord/lib/active_record/associations/has_one_association.rb
index 30704b6f7e..e566089013 100644
--- a/activerecord/lib/active_record/associations/has_one_association.rb
+++ b/activerecord/lib/active_record/associations/has_one_association.rb
@@ -10,8 +10,13 @@ module ActiveRecord
def replace(obj, dont_save = false)
load_target
unless @target.nil?
- @target[@association_class_primary_key_name] = nil
- @target.save unless @owner.new_record?
+ if dependent? && !dont_save
+ @target.destroy unless @target.new_record?
+ @owner.clear_association_cache
+ else
+ @target[@association_class_primary_key_name] = nil
+ @target.save unless @owner.new_record?
+ end
end
if obj.nil?
diff --git a/activerecord/test/associations_test.rb b/activerecord/test/associations_test.rb
index 4a2779227d..b35aadf4ff 100755
--- a/activerecord/test/associations_test.rb
+++ b/activerecord/test/associations_test.rb
@@ -94,7 +94,8 @@ class HasOneAssociationsTest < Test::Unit::TestCase
@signals37.account = nil
@signals37.save
assert_nil @signals37.account
- assert_nil Account.find(old_account_id).firm_id
+ # account is dependent, therefore is destroyed when reference to owner is lost
+ assert_raises(ActiveRecord::RecordNotFound) { Account.find(old_account_id) }
end
def test_dependence