Skip to content

Commit f5eb8f2

Browse files
authored
Merge pull request #451 from seanpdoyle/singleton-callbacks
Singletons: Fix bug that prevented callbacks
2 parents 6dcf2d6 + 6e77556 commit f5eb8f2

File tree

3 files changed

+126
-26
lines changed

3 files changed

+126
-26
lines changed

lib/active_resource/base.rb

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1482,6 +1482,11 @@ def save!
14821482
save || raise(ResourceInvalid.new(self))
14831483
end
14841484

1485+
##
1486+
# :method: destroy
1487+
# :call-seq:
1488+
# destroy
1489+
#
14851490
# Deletes the resource from the remote service.
14861491
#
14871492
# There's a series of callbacks associated with <tt>destroy</tt>. If any
@@ -1498,9 +1503,9 @@ def save!
14981503
# new_id = new_person.id # => 7
14991504
# new_person.destroy
15001505
# Person.find(new_id) # 404 (Resource Not Found)
1501-
def destroy
1506+
def destroy(path = element_path)
15021507
run_callbacks :destroy do
1503-
connection.delete(element_path, self.class.headers)
1508+
connection.delete(path, self.class.headers)
15041509
end
15051510
end
15061511

@@ -1699,9 +1704,9 @@ def connection(refresh = false)
16991704
end
17001705

17011706
# Update the resource on the remote service.
1702-
def _update
1707+
def _update(path = element_path(prefix_options))
17031708
run_callbacks :update do
1704-
connection.put(element_path(prefix_options), encode, self.class.headers).tap do |response|
1709+
connection.put(path, encode, self.class.headers).tap do |response|
17051710
load_attributes_from_response(response)
17061711
end
17071712
end
@@ -1712,9 +1717,9 @@ def _update
17121717
# There's a series of callbacks associated with <tt>create</tt>. If any
17131718
# of the <tt>before_create</tt> callbacks throw +:abort+ the action is
17141719
# cancelled.
1715-
def create
1720+
def create(path = collection_path)
17161721
run_callbacks :create do
1717-
connection.post(collection_path, encode, self.class.headers).tap do |response|
1722+
connection.post(path, encode, self.class.headers).tap do |response|
17181723
self.id = id_from_response(response)
17191724
load_attributes_from_response(response)
17201725
end

lib/active_resource/singleton.rb

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -109,31 +109,32 @@ def find_singleton(options)
109109
instantiate_record(resp, prefix_options)
110110
end
111111
end
112+
113+
##
114+
# :method: destroy
115+
# :call-seq:
116+
# destroy
117+
#
112118
# Deletes the resource from the remote service.
113119
#
114120
# ==== Examples
115121
# weather = Weather.find
116122
# weather.destroy
117123
# Weather.find # 404 (Resource Not Found)
118-
def destroy
119-
connection.delete(singleton_path, self.class.headers)
124+
def destroy(path = singleton_path)
125+
super
120126
end
121127

122128

123129
protected
124130
# Update the resource on the remote service
125-
def _update
126-
connection.put(singleton_path(prefix_options), encode, self.class.headers).tap do |response|
127-
load_attributes_from_response(response)
128-
end
131+
def _update(path = singleton_path)
132+
super
129133
end
130134

131135
# Create (i.e. \save to the remote service) the \new resource.
132-
def create
133-
connection.post(singleton_path, encode, self.class.headers).tap do |response|
134-
self.id = id_from_response(response)
135-
load_attributes_from_response(response)
136-
end
136+
def create(path = singleton_path)
137+
super
137138
end
138139

139140
private

test/cases/callbacks_test.rb

Lines changed: 103 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22

33
require "abstract_unit"
44
require "active_support/core_ext/hash/conversions"
5+
require "active_support/concern"
6+
require "fixtures/weather"
57

6-
class Developer < ActiveResource::Base
7-
self.site = "http://37s.sunrise.i:3000"
8+
module CallbackHistory
9+
extend ActiveSupport::Concern
810

9-
class << self
11+
class_methods do
1012
def callback_string(callback_method)
1113
"history << [#{callback_method.to_sym.inspect}, :string]"
1214
end
@@ -31,28 +33,44 @@ def callback_object(callback_method)
3133
end
3234
end
3335

34-
ActiveResource::Callbacks::CALLBACKS.each do |callback_method|
35-
next if callback_method.to_s =~ /^around_/
36-
define_callback_method(callback_method)
37-
send(callback_method, callback_proc(callback_method))
38-
send(callback_method, callback_object(callback_method))
39-
send(callback_method) { |model| model.history << [ callback_method, :block ] }
36+
included do
37+
ActiveResource::Callbacks::CALLBACKS.each do |callback_method|
38+
next if callback_method.to_s =~ /^around_/
39+
define_callback_method(callback_method)
40+
send(callback_method, callback_proc(callback_method))
41+
send(callback_method, callback_object(callback_method))
42+
send(callback_method) { |model| model.history << [ callback_method, :block ] }
43+
end
4044
end
4145

4246
def history
4347
@history ||= []
4448
end
4549
end
4650

51+
class Developer < ActiveResource::Base
52+
include CallbackHistory
53+
54+
self.site = "http://37s.sunrise.i:3000"
55+
end
56+
57+
Weather.include CallbackHistory
58+
4759
class CallbacksTest < ActiveSupport::TestCase
4860
def setup
4961
@developer_attrs = { id: 1, name: "Guillermo", salary: 100_000 }
5062
@developer = { "developer" => @developer_attrs }.to_json
63+
@weather_attrs = { status: "Sunny", temperature: 67 }
64+
@weather = { weather: @weather_attrs }.to_json
5165
ActiveResource::HttpMock.respond_to do |mock|
5266
mock.post "/developers.json", {}, @developer, 201, "Location" => "/developers/1.json"
5367
mock.get "/developers/1.json", {}, @developer
5468
mock.put "/developers/1.json", {}, nil, 204
5569
mock.delete "/developers/1.json", {}, nil, 200
70+
mock.get "/weather.json", {}, @weather
71+
mock.post "/weather.json", {}, @weather, 201, "Location" => "/weather.json"
72+
mock.delete "/weather.json", {}, nil
73+
mock.put "/weather.json", {}, nil, 204
5674
end
5775
end
5876

@@ -101,6 +119,36 @@ def test_create
101119
], developer.history
102120
end
103121

122+
def test_create_singleton
123+
weather = Weather.create(@weather_attrs)
124+
assert_equal [
125+
[ :before_validation, :method ],
126+
[ :before_validation, :proc ],
127+
[ :before_validation, :object ],
128+
[ :before_validation, :block ],
129+
[ :after_validation, :method ],
130+
[ :after_validation, :proc ],
131+
[ :after_validation, :object ],
132+
[ :after_validation, :block ],
133+
[ :before_save, :method ],
134+
[ :before_save, :proc ],
135+
[ :before_save, :object ],
136+
[ :before_save, :block ],
137+
[ :before_create, :method ],
138+
[ :before_create, :proc ],
139+
[ :before_create, :object ],
140+
[ :before_create, :block ],
141+
[ :after_create, :method ],
142+
[ :after_create, :proc ],
143+
[ :after_create, :object ],
144+
[ :after_create, :block ],
145+
[ :after_save, :method ],
146+
[ :after_save, :proc ],
147+
[ :after_save, :object ],
148+
[ :after_save, :block ]
149+
], weather.history
150+
end
151+
104152
def test_reload
105153
developer = Developer.find(1)
106154
developer.reload
@@ -147,6 +195,37 @@ def test_update
147195
], developer.history
148196
end
149197

198+
def test_update_singleton
199+
weather = Weather.find
200+
weather.save
201+
assert_equal [
202+
[ :before_validation, :method ],
203+
[ :before_validation, :proc ],
204+
[ :before_validation, :object ],
205+
[ :before_validation, :block ],
206+
[ :after_validation, :method ],
207+
[ :after_validation, :proc ],
208+
[ :after_validation, :object ],
209+
[ :after_validation, :block ],
210+
[ :before_save, :method ],
211+
[ :before_save, :proc ],
212+
[ :before_save, :object ],
213+
[ :before_save, :block ],
214+
[ :before_update, :method ],
215+
[ :before_update, :proc ],
216+
[ :before_update, :object ],
217+
[ :before_update, :block ],
218+
[ :after_update, :method ],
219+
[ :after_update, :proc ],
220+
[ :after_update, :object ],
221+
[ :after_update, :block ],
222+
[ :after_save, :method ],
223+
[ :after_save, :proc ],
224+
[ :after_save, :object ],
225+
[ :after_save, :block ]
226+
], weather.history
227+
end
228+
150229
def test_destroy
151230
developer = Developer.find(1)
152231
developer.destroy
@@ -162,6 +241,21 @@ def test_destroy
162241
], developer.history
163242
end
164243

244+
def test_destroy_singleton
245+
weather = Weather.find
246+
weather.destroy
247+
assert_equal [
248+
[ :before_destroy, :method ],
249+
[ :before_destroy, :proc ],
250+
[ :before_destroy, :object ],
251+
[ :before_destroy, :block ],
252+
[ :after_destroy, :method ],
253+
[ :after_destroy, :proc ],
254+
[ :after_destroy, :object ],
255+
[ :after_destroy, :block ]
256+
], weather.history
257+
end
258+
165259
def test_delete
166260
developer = Developer.find(1)
167261
Developer.delete(developer.id)

0 commit comments

Comments
 (0)