diff options
author | Aaron Patterson <aaron.patterson@gmail.com> | 2013-09-11 11:23:11 -0700 |
---|---|---|
committer | Aaron Patterson <aaron.patterson@gmail.com> | 2013-09-11 11:23:30 -0700 |
commit | 7e0cac156eae758a81b2f0f4ac1b18afd7e5354e (patch) | |
tree | 9ce75e20518f44dd0dfffb67f7a69ebdf9ec47ce | |
parent | 233c6d4c298434544e349a559906f5fa1883e070 (diff) | |
download | rails-7e0cac156eae758a81b2f0f4ac1b18afd7e5354e.tar.gz rails-7e0cac156eae758a81b2f0f4ac1b18afd7e5354e.tar.bz2 rails-7e0cac156eae758a81b2f0f4ac1b18afd7e5354e.zip |
fix deleting join models with no pk
-rw-r--r-- | activerecord/lib/active_record/associations/has_many_through_association.rb | 16 | ||||
-rw-r--r-- | activerecord/test/cases/associations/has_many_through_associations_test.rb | 52 |
2 files changed, 62 insertions, 6 deletions
diff --git a/activerecord/lib/active_record/associations/has_many_through_association.rb b/activerecord/lib/active_record/associations/has_many_through_association.rb index a74dd1cdab..56331bbb0b 100644 --- a/activerecord/lib/active_record/associations/has_many_through_association.rb +++ b/activerecord/lib/active_record/associations/has_many_through_association.rb @@ -140,7 +140,21 @@ module ActiveRecord case method when :destroy - count = scope.destroy_all.length + if scope.klass.primary_key + count = scope.destroy_all.length + else + scope.to_a.each do |record| + record.run_callbacks :destroy + end + + arel = scope.arel + + stmt = Arel::DeleteManager.new arel.engine + stmt.from scope.klass.arel_table + stmt.wheres = arel.constraints + + count = scope.klass.connection.delete(stmt, 'SQL', scope.bind_values) + end when :nullify count = scope.update_all(source_reflection.foreign_key => nil) else diff --git a/activerecord/test/cases/associations/has_many_through_associations_test.rb b/activerecord/test/cases/associations/has_many_through_associations_test.rb index 541f649ae9..dd8b426b25 100644 --- a/activerecord/test/cases/associations/has_many_through_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb @@ -65,6 +65,52 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase end def test_no_pk_join_table_append + lesson, _, student = make_no_pk_hm_t + + sicp = lesson.new(:name => "SICP") + ben = student.new(:name => "Ben Bitdiddle") + sicp.students << ben + assert sicp.save! + end + + def test_no_pk_join_table_delete + lesson, lesson_student, student = make_no_pk_hm_t + + sicp = lesson.new(:name => "SICP") + ben = student.new(:name => "Ben Bitdiddle") + louis = student.new(:name => "Louis Reasoner") + sicp.students << ben + sicp.students << louis + assert sicp.save! + + sicp.students.reload + assert_operator lesson_student.count, :>=, 2 + assert_no_difference('student.count') do + assert_difference('lesson_student.count', -2) do + sicp.students.destroy(*student.all.to_a) + end + end + end + + def test_no_pk_join_model_callbacks + lesson, lesson_student, student = make_no_pk_hm_t + + after_destroy_called = false + lesson_student.after_destroy do + after_destroy_called = true + end + + sicp = lesson.new(:name => "SICP") + ben = student.new(:name => "Ben Bitdiddle") + sicp.students << ben + assert sicp.save! + + sicp.students.reload + sicp.students.destroy(*student.all.to_a) + assert after_destroy_called, "after destroy should be called" + end + + def make_no_pk_hm_t lesson = make_model 'Lesson' student = make_model 'Student' @@ -75,11 +121,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase lesson_student.belongs_to :student, :class => student lesson.has_many :lesson_students, :class => lesson_student lesson.has_many :students, :through => :lesson_students, :class => student - - sicp = lesson.new(:name => "SICP") - ben = student.new(:name => "Ben Bitdiddle") - sicp.students << ben - assert sicp.save! + [lesson, lesson_student, student] end def test_pk_is_not_required_for_join |