Make AR::Base#touch fire the after_commit and after_rollback callbacks

This commit is contained in:
Harry Brundage 2013-08-26 13:15:37 -04:00 committed by Carlos Antonio da Silva
parent 38fcee3871
commit 177989c6c0
5 changed files with 71 additions and 2 deletions

View File

@ -1,3 +1,7 @@
* Make `touch` fire the `after_commit` and `after_rollback` callbacks.
*Harry Brundage*
* Enable partial indexes for sqlite >= 3.8.0
See http://www.sqlite.org/partialindex.html

View File

@ -273,6 +273,10 @@ module ActiveRecord
with_transaction_returning_status { super }
end
def touch(*) #:nodoc:
with_transaction_returning_status { super }
end
# Reset id and @new_record if the transaction rolls back.
def rollback_active_record_state!
remember_transaction_record_state

View File

@ -1,9 +1,11 @@
require "cases/helper"
require 'models/owner'
require 'models/pet'
require 'models/topic'
class TransactionCallbacksTest < ActiveRecord::TestCase
self.use_transactional_fixtures = false
fixtures :topics
fixtures :topics, :owners, :pets
class ReplyWithCallbacks < ActiveRecord::Base
self.table_name = :topics
@ -120,6 +122,18 @@ class TransactionCallbacksTest < ActiveRecord::TestCase
assert_equal [], reply.history
end
def test_only_call_after_commit_on_update_after_transaction_commits_for_existing_record_on_touch
@first.after_commit_block(:create){|r| r.history << :commit_on_create}
@first.after_commit_block(:update){|r| r.history << :commit_on_update}
@first.after_commit_block(:destroy){|r| r.history << :commit_on_destroy}
@first.after_rollback_block(:create){|r| r.history << :rollback_on_create}
@first.after_rollback_block(:update){|r| r.history << :rollback_on_update}
@first.after_rollback_block(:destroy){|r| r.history << :rollback_on_destroy}
@first.touch
assert_equal [:commit_on_update], @first.history
end
def test_call_after_rollback_after_transaction_rollsback
@first.after_commit_block{|r| r.history << :after_commit}
@first.after_rollback_block{|r| r.history << :after_rollback}
@ -148,6 +162,22 @@ class TransactionCallbacksTest < ActiveRecord::TestCase
assert_equal [:rollback_on_update], @first.history
end
def test_only_call_after_rollback_on_update_after_transaction_rollsback_for_existing_record_on_touch
@first.after_commit_block(:create){|r| r.history << :commit_on_create}
@first.after_commit_block(:update){|r| r.history << :commit_on_update}
@first.after_commit_block(:destroy){|r| r.history << :commit_on_destroy}
@first.after_rollback_block(:create){|r| r.history << :rollback_on_create}
@first.after_rollback_block(:update){|r| r.history << :rollback_on_update}
@first.after_rollback_block(:destroy){|r| r.history << :rollback_on_destroy}
Topic.transaction do
@first.touch
raise ActiveRecord::Rollback
end
assert_equal [:rollback_on_update], @first.history
end
def test_only_call_after_rollback_on_destroy_after_transaction_rollsback_for_destroyed_record
@first.after_commit_block(:create){|r| r.history << :commit_on_create}
@first.after_commit_block(:update){|r| r.history << :commit_on_update}
@ -279,6 +309,21 @@ class TransactionCallbacksTest < ActiveRecord::TestCase
def test_after_commit_callbacks_should_validate_on_condition
assert_raise(ArgumentError) { Topic.send(:after_commit, :on => :save) }
end
def test_saving_a_record_with_a_belongs_to_that_specifies_touching_the_parent_should_call_callbacks_on_the_parent_object
pet = Pet.first
owner = pet.owner
flag = false
owner.on_after_commit do
flag = true
end
pet.name = "Fluffy the Third"
pet.save
assert flag
end
end
class CallbacksOnMultipleActionsTest < ActiveRecord::TestCase

View File

@ -15,7 +15,6 @@ class Car < ActiveRecord::Base
scope :incl_engines, -> { includes(:engines) }
scope :order_using_new_style, -> { order('name asc') }
end
class CoolCar < Car

View File

@ -2,4 +2,21 @@ class Owner < ActiveRecord::Base
self.primary_key = :owner_id
has_many :pets, -> { order 'pets.name desc' }
has_many :toys, :through => :pets
after_commit :execute_blocks
def blocks
@blocks ||= []
end
def on_after_commit(&block)
blocks << block
end
def execute_blocks
blocks.each do |block|
block.call(self)
end
@blocks = []
end
end