Skip to content

Commit d488fe1

Browse files
authored
Merge pull request #414 from seanpdoyle/reload_callbacks
Add `before_reload`, `after_reload`, and `around_reload` callbacks
2 parents 0019d7d + 8a929b0 commit d488fe1

File tree

4 files changed

+83
-6
lines changed

4 files changed

+83
-6
lines changed

lib/active_resource/base.rb

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1380,6 +1380,10 @@ def dup
13801380
# is Json for the final object as it looked after the \save (which would include attributes like +created_at+
13811381
# that weren't part of the original submit).
13821382
#
1383+
# There's a series of callbacks associated with <tt>save</tt>. If any
1384+
# of the <tt>before_*</tt> callbacks throw +:abort+ the action is
1385+
# cancelled and <tt>save</tt> raises ActiveResource::ResourceInvalid.
1386+
#
13831387
# ==== Examples
13841388
# my_company = Company.new(:name => 'RoleModel Software', :owner => 'Ken Auer', :size => 2)
13851389
# my_company.new? # => true
@@ -1405,14 +1409,18 @@ def save
14051409
# See ActiveResource::Validations for more information.
14061410
#
14071411
# There's a series of callbacks associated with <tt>save!</tt>. If any
1408-
# of the <tt>before_*</tt> callbacks return +false+ the action is
1412+
# of the <tt>before_*</tt> callbacks throw +:abort+ the action is
14091413
# cancelled and <tt>save!</tt> raises ActiveResource::ResourceInvalid.
14101414
def save!
14111415
save || raise(ResourceInvalid.new(self))
14121416
end
14131417

14141418
# Deletes the resource from the remote service.
14151419
#
1420+
# There's a series of callbacks associated with <tt>destroy</tt>. If any
1421+
# of the <tt>before_destroy</tt> callbacks throw +:abort+ the action is
1422+
# cancelled.
1423+
#
14161424
# ==== Examples
14171425
# my_id = 3
14181426
# my_person = Person.find(my_id)
@@ -1468,9 +1476,9 @@ def encode(options = {})
14681476
# my_branch.reload
14691477
# my_branch.name # => "Wilson Road"
14701478
def reload
1471-
self.load(self.class.find(to_param, params: @prefix_options).attributes, false, true)
1472-
rescue => exception
1473-
rescue_with_handler(exception) || raise
1479+
run_callbacks :reload do
1480+
self.load(self.class.find(to_param, params: @prefix_options).attributes, false, true)
1481+
end
14741482
end
14751483

14761484
# A method to manually load attributes from a \hash. Recursively loads collections of
@@ -1614,6 +1622,10 @@ def update
16141622
end
16151623

16161624
# Create (i.e., \save to the remote service) the \new resource.
1625+
#
1626+
# There's a series of callbacks associated with <tt>create</tt>. If any
1627+
# of the <tt>before_create</tt> callbacks throw +:abort+ the action is
1628+
# cancelled.
16171629
def create
16181630
run_callbacks :create do
16191631
connection.post(collection_path, encode, self.class.headers).tap do |response|

lib/active_resource/callbacks.rb

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,69 @@
33
require "active_support/core_ext/array/wrap"
44

55
module ActiveResource
6+
# = Active Resource \Callbacks
7+
#
8+
# \Callbacks are hooks into the life cycle of an Active Resource object that allow you to trigger logic
9+
# before or after a change in the object state. Active Resources instances trigger callbacks for the following methods:
10+
#
11+
# * <tt>save</tt> (<tt>around_save</tt>, <tt>before_save</tt>, <tt>after_save</tt>)
12+
# * <tt>create</tt> (<tt>around_create</tt>, <tt>before_create</tt>, <tt>after_create</tt>)
13+
# * <tt>update</tt> (<tt>around_update</tt>, <tt>before_update</tt>, <tt>after_update</tt>)
14+
# * <tt>destroy</tt> (<tt>around_destroy</tt>, <tt>before_destroy</tt>, <tt>after_destroy</tt>)
15+
# * <tt>reload</tt> (<tt>around_reload</tt>, <tt>before_reload</tt>, <tt>after_reload</tt>)
16+
#
17+
# As an example of the callbacks initiated, consider the {ActiveResource::Base#save}[rdoc-ref:Base#save] call for a new resource:
18+
#
19+
# * (-) <tt>save</tt>
20+
# * (-) <tt>valid?</tt>
21+
# * (1) <tt>before_validation</tt>
22+
# * (-) <tt>validate</tt>
23+
# * (2) <tt>after_validation</tt>
24+
# * (3) <tt>before_save</tt>
25+
# * (4) <tt>before_create</tt>
26+
# * (-) <tt>create</tt>
27+
# * (5) <tt>after_create</tt>
28+
# * (6) <tt>after_save</tt>
29+
#
30+
# == Canceling callbacks
31+
#
32+
# If a <tt>before_*</tt> callback throws +:abort+, all the later callbacks and
33+
# the associated action are cancelled.
34+
# \Callbacks are generally run in the order they are defined, with the exception of callbacks defined as
35+
# methods on the model, which are called last.
36+
#
37+
# == Debugging callbacks
38+
#
39+
# The callback chain is accessible via the <tt>_*_callbacks</tt> method on an object. Active Model \Callbacks support
40+
# <tt>:before</tt>, <tt>:after</tt> and <tt>:around</tt> as values for the <tt>kind</tt> property. The <tt>kind</tt> property
41+
# defines what part of the chain the callback runs in.
42+
#
43+
# To find all callbacks in the +before_save+ callback chain:
44+
#
45+
# Topic._save_callbacks.select { |cb| cb.kind.eql?(:before) }
46+
#
47+
# Returns an array of callback objects that form the +before_save+ chain.
48+
#
49+
# To further check if the before_save chain contains a proc defined as <tt>rest_when_dead</tt> use the <tt>filter</tt> property of the callback object:
50+
#
51+
# Topic._save_callbacks.select { |cb| cb.kind.eql?(:before) }.collect(&:filter).include?(:rest_when_dead)
52+
#
53+
# Returns true or false depending on whether the proc is contained in the +before_save+ callback chain on a Topic model.
654
module Callbacks
755
extend ActiveSupport::Concern
856

957
CALLBACKS = [
1058
:before_validation, :after_validation, :before_save, :around_save, :after_save,
1159
:before_create, :around_create, :after_create, :before_update, :around_update,
12-
:after_update, :before_destroy, :around_destroy, :after_destroy
60+
:after_update, :before_destroy, :around_destroy, :after_destroy,
61+
:before_reload, :around_reload, :after_reload
1362
]
1463

1564
included do
1665
extend ActiveModel::Callbacks
1766
include ActiveModel::Validations::Callbacks
1867

19-
define_model_callbacks :save, :create, :update, :destroy
68+
define_model_callbacks :save, :create, :update, :destroy, :reload
2069
end
2170
end
2271
end

lib/active_resource/rescuable.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ module Rescuable
1414

1515
around_save :handle_exceptions
1616
around_destroy :handle_exceptions
17+
around_reload :handle_exceptions
1718
end
1819

1920
private

test/cases/callbacks_test.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,21 @@ def test_create
101101
], developer.history
102102
end
103103

104+
def test_reload
105+
developer = Developer.find(1)
106+
developer.reload
107+
assert_equal [
108+
[ :before_reload, :method ],
109+
[ :before_reload, :proc ],
110+
[ :before_reload, :object ],
111+
[ :before_reload, :block ],
112+
[ :after_reload, :method ],
113+
[ :after_reload, :proc ],
114+
[ :after_reload, :object ],
115+
[ :after_reload, :block ]
116+
], developer.history
117+
end
118+
104119
def test_update
105120
developer = Developer.find(1)
106121
developer.save

0 commit comments

Comments
 (0)