From c6055134b5e8bb0807ba79d2150c4d20e1271229 Mon Sep 17 00:00:00 2001 From: Hongli Lai (Phusion) Date: Sun, 21 Sep 2008 23:01:32 +0200 Subject: [PATCH] Add an ActiveRecord::Base#delete instance method. This method is like #destroy, but does not call before_destroy hooks and such. --- activerecord/lib/active_record/associations.rb | 4 +- activerecord/lib/active_record/base.rb | 16 ++++++++++++ activerecord/test/cases/base_test.rb | 30 ++++++++++++++++++++++- 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index e6491ce..3cad914 100755 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1470,7 +1470,7 @@ module ActiveRecord method_name = "has_one_dependent_delete_for_#{reflection.name}".to_sym define_method(method_name) do association = send(reflection.name) - association.class.delete(association.id) unless association.nil? + association.delete unless association.nil? unless association.nil? end before_destroy method_name when :nullify @@ -1500,7 +1500,7 @@ module ActiveRecord method_name = "belongs_to_dependent_delete_for_#{reflection.name}".to_sym define_method(method_name) do association = send(reflection.name) - association.class.delete(association.id) unless association.nil? + association.delete unless association.nil? end before_destroy method_name else diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index b20da51..6d6fcb7 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -2306,6 +2306,22 @@ module ActiveRecord #:nodoc: # Deletes the record in the database and freezes this instance to reflect that no changes should # be made (since they can't be persisted). + # + # Unlike #destroy, this method doesn't run any +before_delete+ and +after_delete+ + # callbacks, nor will it enforce any association +:dependent+ rules. + def delete + unless new_record? + connection.delete <<-end_sql, "#{self.class.name} Delete" + DELETE FROM #{self.class.quoted_table_name} + WHERE #{connection.quote_column_name(self.class.primary_key)} = #{quoted_id} + end_sql + end + + freeze + end + + # Deletes the record in the database and freezes this instance to reflect that no changes should + # be made (since they can't be persisted). def destroy unless new_record? connection.delete <<-end_sql, "#{self.class.name} Destroy" diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index aebcca6..b35b0d6 100644 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -471,6 +471,18 @@ class BasicsTest < ActiveRecord::TestCase topic.send(:approved=, true) assert topic.instance_variable_get("@custom_approved") end + + def test_delete + topic = Topic.find(1) + assert_equal topic, topic.delete, 'topic.delete did not return self' + assert topic.frozen?, 'topic not frozen after delete' + assert_raise(ActiveRecord::RecordNotFound) { Topic.find(topic.id) } + end + + def test_delete_doesnt_run_callbacks + Topic.find(1).delete + assert_not_nil Topic.find(2) + end def test_destroy topic = Topic.find(1) @@ -696,7 +708,7 @@ class BasicsTest < ActiveRecord::TestCase assert_equal Topic.count, Topic.delete_all end - + def test_update_by_condition Topic.update_all "content = 'bulk updated!'", ["approved = ?", true] assert_equal "Have a nice day", Topic.find(1).content @@ -819,7 +831,21 @@ class BasicsTest < ActiveRecord::TestCase def test_hashing assert_equal [ Topic.find(1) ], [ Topic.find(2).topic ] & [ Topic.find(1) ] end - + + def test_delete_new_record + client = Client.new + client.delete + assert client.frozen? + end + + def test_delete_record_with_associations + client = Client.find(3) + client.delete + assert client.frozen? + assert_kind_of Firm, client.firm + assert_raises(ActiveSupport::FrozenObjectError) { client.name = "something else" } + end + def test_destroy_new_record client = Client.new client.destroy -- 1.6.0.2