aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2005-05-02 16:46:30 +0000
committerDavid Heinemeier Hansson <david@loudthinking.com>2005-05-02 16:46:30 +0000
commit24a9050b6e34c859909f4e16ee68b8b34407a771 (patch)
tree777e5811e895dedfa83ade91b17a1a1d2b1db147 /activerecord
parent74a612c4a15f3094e478aa79eb63b27efec8358a (diff)
downloadrails-24a9050b6e34c859909f4e16ee68b8b34407a771.tar.gz
rails-24a9050b6e34c859909f4e16ee68b8b34407a771.tar.bz2
rails-24a9050b6e34c859909f4e16ee68b8b34407a771.zip
Changed the callbacks such that observers are notified before the in-object callbacks are triggered. Without this change, it wasn't possible to act on the whole object in something like a before_destroy observer without having the objects own callbacks (like deleting associations) called first.
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1273 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/CHANGELOG2
-rwxr-xr-xactiverecord/lib/active_record/base.rb9
-rwxr-xr-xactiverecord/lib/active_record/callbacks.rb11
-rwxr-xr-xactiverecord/test/base_test.rb9
4 files changed, 26 insertions, 5 deletions
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG
index 56ec6c80be..7d6a7c9a50 100644
--- a/activerecord/CHANGELOG
+++ b/activerecord/CHANGELOG
@@ -1,5 +1,7 @@
*SVN*
+* Changed the callbacks such that observers are notified before the in-object callbacks are triggered. Without this change, it wasn't possible to act on the whole object in something like a before_destroy observer without having the objects own callbacks (like deleting associations) called first.
+
* Added option for passing an array to the find_all version of the dynamic finders and have it evaluated as an IN fragment. Example:
# SELECT * FROM topics WHERE title IN ('First', 'Second')
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index a74f8ce471..4705d9359c 100755
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -1128,6 +1128,15 @@ module ActiveRecord #:nodoc:
self.class.column_methods_hash[method.to_sym] || respond_to_without_attributes?(method, include_priv)
end
+ # Just freeze the attributes hash, such that associations are still accessible even on destroyed records.
+ def freeze
+ @attributes.freeze
+ end
+
+ def frozen?
+ @attributes.frozen?
+ end
+
private
def create_or_update
if new_record? then create else update end
diff --git a/activerecord/lib/active_record/callbacks.rb b/activerecord/lib/active_record/callbacks.rb
index 23675c3bd4..57745b344e 100755
--- a/activerecord/lib/active_record/callbacks.rb
+++ b/activerecord/lib/active_record/callbacks.rb
@@ -328,6 +328,8 @@ module ActiveRecord
private
def callback(method)
+ notify(method)
+
callbacks_for(method).each do |callback|
result = case callback
when Symbol
@@ -345,9 +347,10 @@ module ActiveRecord
end
return false if result == false
end
-
- invoke_and_notify(method)
- true
+
+ send(method) if respond_to_without_attributes?(method)
+
+ return true
end
def callbacks_for(method)
@@ -355,8 +358,8 @@ module ActiveRecord
end
def invoke_and_notify(method)
- send(method) if respond_to_without_attributes?(method)
notify(method)
+ send(method) if respond_to_without_attributes?(method)
end
def notify(method) #:nodoc:
diff --git a/activerecord/test/base_test.rb b/activerecord/test/base_test.rb
index 595450eab9..9185d05c8a 100755
--- a/activerecord/test/base_test.rb
+++ b/activerecord/test/base_test.rb
@@ -200,7 +200,6 @@ class BasicsTest < Test::Unit::TestCase
topic.written_on = "2003-12-12 23:23:00"
topic.save
topic.destroy
- assert_raise(TypeError) { topic.save }
assert_raise(ActiveRecord::RecordNotFound) { Topic.find(topic.id) }
end
@@ -434,6 +433,14 @@ class BasicsTest < Test::Unit::TestCase
assert client.frozen?
end
+ def test_destroy_record_with_associations
+ client = Client.find(3)
+ client.destroy
+ assert client.frozen?
+ assert_kind_of Firm, client.firm
+ assert_raises(TypeError) { client.name = "something else" }
+ end
+
def test_update_attribute
assert !Topic.find(1).approved?
Topic.find(1).update_attribute("approved", true)