aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2013-09-11 11:23:11 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2013-09-11 11:23:30 -0700
commit7e0cac156eae758a81b2f0f4ac1b18afd7e5354e (patch)
tree9ce75e20518f44dd0dfffb67f7a69ebdf9ec47ce
parent233c6d4c298434544e349a559906f5fa1883e070 (diff)
downloadrails-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.rb16
-rw-r--r--activerecord/test/cases/associations/has_many_through_associations_test.rb52
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