From af95d7bc854b151a4301abdf8f21d8b3fe4bcad3 Mon Sep 17 00:00:00 2001 From: Edward Faulkner Date: Fri, 4 Feb 2011 15:34:44 -0500 Subject: [PATCH] Fixing ordering of HABTM association deletion [#6191 state:resolved] --- activerecord/lib/active_record/associations.rb | 2 +- .../has_and_belongs_to_many_associations_test.rb | 2 +- .../test/cases/habtm_destroy_order_test.rb | 17 +++++++++++++++++ activerecord/test/models/lesson.rb | 11 +++++++++++ activerecord/test/models/student.rb | 3 +++ activerecord/test/schema/schema.rb | 13 +++++++++++++ 6 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 activerecord/test/cases/habtm_destroy_order_test.rb create mode 100644 activerecord/test/models/lesson.rb create mode 100644 activerecord/test/models/student.rb diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 891ac52..d30362b 100644 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1450,8 +1450,8 @@ module ActiveRecord include Module.new { class_eval <<-RUBY, __FILE__, __LINE__ + 1 def destroy # def destroy - #{reflection.name}.clear # posts.clear super # super + #{reflection.name}.clear # posts.clear end # end RUBY } diff --git a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb index 30730c7..55b611c 100644 --- a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb @@ -365,7 +365,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase def test_removing_associations_on_destroy david = DeveloperWithBeforeDestroyRaise.find(1) assert !david.projects.empty? - assert_raise(RuntimeError) { david.destroy } + david.destroy assert david.projects.empty? assert DeveloperWithBeforeDestroyRaise.connection.select_all("SELECT * FROM developers_projects WHERE developer_id = 1").empty? end diff --git a/activerecord/test/cases/habtm_destroy_order_test.rb b/activerecord/test/cases/habtm_destroy_order_test.rb new file mode 100644 index 0000000..1559839 --- /dev/null +++ b/activerecord/test/cases/habtm_destroy_order_test.rb @@ -0,0 +1,17 @@ +require "cases/helper" +require "models/lesson" +require "models/student" + +class HabtmDestroyOrderTest < ActiveRecord::TestCase + test "may not delete a lesson with students" do + sicp = Lesson.new(:name => "SICP") + ben = Student.new(:name => "Ben Bitdiddle") + sicp.students << ben + sicp.save! + assert_raises LessonError do + assert_no_difference('Lesson.count') do + sicp.destroy + end + end + end +end diff --git a/activerecord/test/models/lesson.rb b/activerecord/test/models/lesson.rb new file mode 100644 index 0000000..4c88153 --- /dev/null +++ b/activerecord/test/models/lesson.rb @@ -0,0 +1,11 @@ +class LessonError < Exception +end + +class Lesson < ActiveRecord::Base + has_and_belongs_to_many :students + before_destroy :ensure_no_students + + def ensure_no_students + raise LessonError unless students.empty? + end +end diff --git a/activerecord/test/models/student.rb b/activerecord/test/models/student.rb new file mode 100644 index 0000000..f459f2a --- /dev/null +++ b/activerecord/test/models/student.rb @@ -0,0 +1,3 @@ +class Student < ActiveRecord::Base + has_and_belongs_to_many :lessons +end diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb index 5f9bb7e..326c336 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -279,6 +279,15 @@ ActiveRecord::Schema.define do t.integer :version, :null => false, :default => 0 end + create_table :lessons, :force => true do |t| + t.string :name + end + + create_table :lessons_students, :id => false, :force => true do |t| + t.references :lesson + t.references :student + end + create_table :line_items, :force => true do |t| t.integer :invoice_id t.integer :amount @@ -509,6 +518,10 @@ ActiveRecord::Schema.define do t.string :sponsorable_type end + create_table :students, :force => true do |t| + t.string :name + end + create_table :subscribers, :force => true, :id => false do |t| t.string :nick, :null => false t.string :name -- 1.7.3.2