Skip to content

Commit 51dfdb5

Browse files
committed
Change Base#update to accept attributes
If the intent of Active Resource to be similar enough to Active Record for its users to be able to intuit its interfaces, the absence of `Base#update` can is a surprise. Prior to this commit, the was an existent `Base#update` protected method that handles issuing the `PUT` request. Its interface is more akin to `Base#save`, in that it did not accept attributes. This commit foists that method from being `protected` to be `public`. It changes the interface to accept attributes. It retains the original implementation when the `attributes` argument is omitted (for the sake of backwards compatibility). When `attributes` are provided, forward them to the `Base#update_attributes` method. Explicitly document the interface that indicates that the only way for public callers to invoke the method if with an `attributes` argument. This commit also implements the `Base#update_attribute` method in terms of the `Base#update_attributes` method.
1 parent b549319 commit 51dfdb5

File tree

3 files changed

+63
-5
lines changed

3 files changed

+63
-5
lines changed

lib/active_resource/base.rb

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1461,7 +1461,7 @@ def dup
14611461
# my_company.save # sends PUT /companies/1 (update)
14621462
def save
14631463
run_callbacks :save do
1464-
new? ? create : update
1464+
new? ? create : _update
14651465
end
14661466
end
14671467

@@ -1623,8 +1623,7 @@ def load(attributes, remove_root = false, persisted = false)
16231623
# exception will be raised. If saving fails because the resource is
16241624
# invalid then <tt>false</tt> will be returned.
16251625
def update_attribute(name, value)
1626-
self.send("#{name}=".to_sym, value)
1627-
self.save
1626+
update_attributes(name => value)
16281627
end
16291628

16301629
# Updates this resource with all the attributes from the passed-in Hash
@@ -1641,6 +1640,22 @@ def update_attributes(attributes)
16411640
load(attributes, false) && save
16421641
end
16431642

1643+
##
1644+
# :method: update
1645+
# :call-seq:
1646+
# update(attributes)
1647+
#
1648+
# Equivalent to update_attributes(attributes).
1649+
def update(attributes = nil)
1650+
if attributes
1651+
update_attributes(attributes)
1652+
else
1653+
ActiveResource.deprecator.warn("Calling update without arguments is deprecated. Use save instead")
1654+
1655+
_update
1656+
end
1657+
end
1658+
16441659
# For checking <tt>respond_to?</tt> without searching the attributes (which is faster).
16451660
alias_method :respond_to_without_attributes?, :respond_to?
16461661

@@ -1684,7 +1699,7 @@ def connection(refresh = false)
16841699
end
16851700

16861701
# Update the resource on the remote service.
1687-
def update
1702+
def _update
16881703
run_callbacks :update do
16891704
connection.put(element_path(prefix_options), encode, self.class.headers).tap do |response|
16901705
load_attributes_from_response(response)

lib/active_resource/singleton.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ def destroy
122122

123123
protected
124124
# Update the resource on the remote service
125-
def update
125+
def _update
126126
connection.put(singleton_path(prefix_options), encode, self.class.headers).tap do |response|
127127
load_attributes_from_response(response)
128128
end

test/cases/base_test.rb

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1256,6 +1256,49 @@ def test_update_attributes_as_strings
12561256
assert_equal "USA", addy.country
12571257
end
12581258

1259+
def test_deprecates_caliing_update_without_arguments
1260+
ActiveResource::HttpMock.respond_to.put "/posts/1.json", @default_request_headers
1261+
1262+
post = Post.new({ id: 1 }, true)
1263+
1264+
assert_deprecated "", ActiveResource.deprecator do
1265+
post.update
1266+
end
1267+
assert_equal post.encode, ActiveResource::HttpMock.requests.last.body
1268+
end
1269+
1270+
def test_symbols_to_update
1271+
ActiveResource::HttpMock.respond_to.put "/posts/1.json", @default_request_headers
1272+
1273+
post = Post.new({ id: 1, title: "hello" }, true)
1274+
1275+
assert_changes -> { post.title }, from: "hello", to: "goodbye" do
1276+
post.update(title: "goodbye")
1277+
end
1278+
assert_equal post.encode, ActiveResource::HttpMock.requests.last.body
1279+
end
1280+
1281+
def test_strings_to_update
1282+
ActiveResource::HttpMock.respond_to.put "/posts/1.json", @default_request_headers
1283+
1284+
post = Post.new({ id: 1, title: "hello" }, true)
1285+
1286+
assert_changes -> { post.title }, from: "hello", to: "goodbye" do
1287+
post.update("title" => "goodbye")
1288+
end
1289+
assert_equal post.encode, ActiveResource::HttpMock.requests.last.body
1290+
end
1291+
1292+
def test_raises_error_from_failed_update
1293+
ActiveResource::HttpMock.respond_to.put "/posts/1.json", @default_request_headers, nil, 400
1294+
1295+
post = Post.new({ id: 1, title: "hello" }, true)
1296+
1297+
assert_raises ActiveResource::BadRequest do
1298+
post.update(title: "goodbye")
1299+
end
1300+
assert_equal post.encode, ActiveResource::HttpMock.requests.last.body
1301+
end
12591302

12601303
#####
12611304
# Mayhem and destruction

0 commit comments

Comments
 (0)