aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorJeremy Kemper <jeremy@bitsweat.net>2007-10-27 20:31:09 +0000
committerJeremy Kemper <jeremy@bitsweat.net>2007-10-27 20:31:09 +0000
commit88f951a519d750236cc157566ef10f3977c933e1 (patch)
tree4966713bd6ec54a9cca12ba4c56ba25b8e81b81f /activerecord
parenta55caf666cf4c00bdc5d73ac21ef92d6456cdf62 (diff)
downloadrails-88f951a519d750236cc157566ef10f3977c933e1.tar.gz
rails-88f951a519d750236cc157566ef10f3977c933e1.tar.bz2
rails-88f951a519d750236cc157566ef10f3977c933e1.zip
Allow association redefinition in subclasses. Closes #9346.
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@8046 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/CHANGELOG2
-rwxr-xr-xactiverecord/lib/active_record/associations.rb6
-rw-r--r--activerecord/test/aggregations_test.rb18
-rwxr-xr-xactiverecord/test/associations_test.rb65
4 files changed, 89 insertions, 2 deletions
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG
index 6847755e6e..1875eda3ba 100644
--- a/activerecord/CHANGELOG
+++ b/activerecord/CHANGELOG
@@ -1,5 +1,7 @@
*SVN*
+* Allow association redefinition in subclasses. #9346 [wildchild]
+
* Fix has_many :through delete with custom foreign keys. #6466 [naffis]
* Foxy fixtures, from rathole (http://svn.geeksomnia.com/rathole/trunk/README)
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index e542e8d85a..654b24d71c 100755
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -955,7 +955,7 @@ module ActiveRecord
# Don't use a before_destroy callback since users' before_destroy
# callbacks will be executed after the association is wiped out.
old_method = "destroy_without_habtm_shim_for_#{reflection.name}"
- class_eval <<-end_eval
+ class_eval <<-end_eval unless method_defined?(old_method)
alias_method :#{old_method}, :destroy_without_callbacks
def destroy_without_callbacks
#{reflection.name}.clear
@@ -1351,7 +1351,9 @@ module ActiveRecord
defined_callbacks = options[callback_name.to_sym]
if options.has_key?(callback_name.to_sym)
class_inheritable_reader full_callback_name.to_sym
- write_inheritable_array(full_callback_name.to_sym, [defined_callbacks].flatten)
+ write_inheritable_attribute(full_callback_name.to_sym, [defined_callbacks].flatten)
+ else
+ write_inheritable_attribute(full_callback_name.to_sym, [])
end
end
end
diff --git a/activerecord/test/aggregations_test.rb b/activerecord/test/aggregations_test.rb
index 89927e5044..299e0484e3 100644
--- a/activerecord/test/aggregations_test.rb
+++ b/activerecord/test/aggregations_test.rb
@@ -108,3 +108,21 @@ class AggregationsTest < Test::Unit::TestCase
assert_equal nil, customers(:david).gps_location
end
end
+
+class OverridingAggregationsTest < Test::Unit::TestCase
+ class Name; end
+ class DifferentName; end
+
+ class Person < ActiveRecord::Base
+ composed_of :composed_of, :mapping => %w(person_first_name first_name)
+ end
+
+ class DifferentPerson < Person
+ composed_of :composed_of, :class_name => 'DifferentName', :mapping => %w(different_person_first_name first_name)
+ end
+
+ def test_composed_of_aggregation_redefinition_reflections_should_differ_and_not_inherited
+ assert_not_equal Person.reflect_on_aggregation(:composed_of),
+ DifferentPerson.reflect_on_aggregation(:composed_of)
+ end
+end
diff --git a/activerecord/test/associations_test.rb b/activerecord/test/associations_test.rb
index 121a8c5ac4..1fe8d2a417 100755
--- a/activerecord/test/associations_test.rb
+++ b/activerecord/test/associations_test.rb
@@ -1932,3 +1932,68 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
end
end
end
+
+
+class OverridingAssociationsTest < Test::Unit::TestCase
+ class Person < ActiveRecord::Base; end
+ class DifferentPerson < ActiveRecord::Base; end
+
+ class PeopleList < ActiveRecord::Base
+ has_and_belongs_to_many :has_and_belongs_to_many, :before_add => :enlist
+ has_many :has_many, :before_add => :enlist
+ belongs_to :belongs_to
+ has_one :has_one
+ end
+
+ class DifferentPeopleList < PeopleList
+ # Different association with the same name, callbacks should be omitted here.
+ has_and_belongs_to_many :has_and_belongs_to_many, :class_name => 'DifferentPerson'
+ has_many :has_many, :class_name => 'DifferentPerson'
+ belongs_to :belongs_to, :class_name => 'DifferentPerson'
+ has_one :has_one, :class_name => 'DifferentPerson'
+ end
+
+ def test_habtm_association_redefinition_callbacks_should_differ_and_not_inherited
+ # redeclared association on AR descendant should not inherit callbacks from superclass
+ callbacks = PeopleList.read_inheritable_attribute(:before_add_for_has_and_belongs_to_many)
+ assert_equal([:enlist], callbacks)
+ callbacks = DifferentPeopleList.read_inheritable_attribute(:before_add_for_has_and_belongs_to_many)
+ assert_equal([], callbacks)
+ end
+
+ def test_has_many_association_redefinition_callbacks_should_differ_and_not_inherited
+ # redeclared association on AR descendant should not inherit callbacks from superclass
+ callbacks = PeopleList.read_inheritable_attribute(:before_add_for_has_many)
+ assert_equal([:enlist], callbacks)
+ callbacks = DifferentPeopleList.read_inheritable_attribute(:before_add_for_has_many)
+ assert_equal([], callbacks)
+ end
+
+ def test_habtm_association_redefinition_reflections_should_differ_and_not_inherited
+ assert_not_equal(
+ PeopleList.reflect_on_association(:has_and_belongs_to_many),
+ DifferentPeopleList.reflect_on_association(:has_and_belongs_to_many)
+ )
+ end
+
+ def test_has_many_association_redefinition_reflections_should_differ_and_not_inherited
+ assert_not_equal(
+ PeopleList.reflect_on_association(:has_many),
+ DifferentPeopleList.reflect_on_association(:has_many)
+ )
+ end
+
+ def test_belongs_to_association_redefinition_reflections_should_differ_and_not_inherited
+ assert_not_equal(
+ PeopleList.reflect_on_association(:belongs_to),
+ DifferentPeopleList.reflect_on_association(:belongs_to)
+ )
+ end
+
+ def test_has_one_association_redefinition_reflections_should_differ_and_not_inherited
+ assert_not_equal(
+ PeopleList.reflect_on_association(:has_one),
+ DifferentPeopleList.reflect_on_association(:has_one)
+ )
+ end
+end