Skip to content

Commit b21bec6

Browse files
authored
Merge pull request #431 from seanpdoyle/coder-remove-root
`Coder#load`: Conditionally call `Formats.remove_root`
2 parents 583ad1b + 4e7d675 commit b21bec6

File tree

2 files changed

+34
-17
lines changed

2 files changed

+34
-17
lines changed

lib/active_resource/coder.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ def load(value)
7070
return if value.nil?
7171
value = resource_class.format.decode(value) if value.is_a?(String)
7272
raise ArgumentError.new("expected value to be Hash, but was #{value.class}") unless value.is_a?(Hash)
73+
value = Formats.remove_root(value) if value.keys.first.to_s == resource_class.element_name
74+
7375
resource_class.new(value, value[resource_class.primary_key])
7476
end
7577
end

test/cases/base/serialization_test.rb

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ class SerializationTest < ActiveSupport::TestCase
100100
test "#load decodes a Hash into an instance" do
101101
resource = Person.new(id: 1, name: "Matz")
102102

103-
decoded = Person.coder.load(resource.serializable_hash)
103+
decoded = Person.coder.load(JSON.parse(resource.encode))
104104

105105
assert_equal resource.id, decoded.id
106106
assert_equal resource.name, decoded.name
@@ -110,45 +110,52 @@ class SerializationTest < ActiveSupport::TestCase
110110
test "#load builds the instance as persisted when the default primary key is present" do
111111
resource = Person.new(id: 1, name: "Matz")
112112

113-
decoded = Person.coder.load(resource.encode)
113+
[ resource.encode, JSON.parse(resource.encode) ].each do |encoded|
114+
decoded = Person.coder.load(encoded)
114115

115-
assert_predicate decoded, :persisted?
116-
assert_not_predicate decoded, :new_record?
116+
assert_predicate decoded, :persisted?
117+
assert_not_predicate decoded, :new_record?
118+
end
117119
end
118120

119121
test "#load builds the instance as persisted when the configured primary key is present" do
120122
previous_value, Person.primary_key = Person.primary_key, "pk"
121123
resource = Person.new(pk: 1, name: "Matz")
122124

123-
decoded = Person.coder.load(resource.encode)
125+
[ resource.encode, JSON.parse(resource.encode) ].each do |encoded|
126+
decoded = Person.coder.load(encoded)
124127

125-
assert_equal 1, decoded.id
126-
assert_predicate decoded, :persisted?
127-
assert_not_predicate decoded, :new_record?
128+
assert_equal 1, decoded.id
129+
assert_predicate decoded, :persisted?
130+
assert_not_predicate decoded, :new_record?
131+
end
128132
ensure
129133
Person.primary_key = previous_value
130134
end
131135

132136
test "#load builds the instance as a new record when the default primary key is absent" do
133137
resource = Person.new(name: "Matz")
134138

135-
decoded = Person.coder.load(resource.encode)
139+
[ resource.encode, JSON.parse(resource.encode) ].each do |encoded|
140+
decoded = Person.coder.load(encoded)
136141

137-
assert_nil decoded.id
138-
assert_not_predicate decoded, :persisted?
139-
assert_predicate decoded, :new_record?
142+
assert_nil decoded.id
143+
assert_not_predicate decoded, :persisted?
144+
assert_predicate decoded, :new_record?
145+
end
140146
end
141147

142148
test "#load builds the instance as a new record when the configured primary key is absent" do
143149
previous_value, Person.primary_key = Person.primary_key, "pk"
144-
145150
resource = Person.new(name: "Matz")
146151

147-
decoded = Person.coder.load(resource.encode)
152+
[ resource.encode, JSON.parse(resource.encode) ].each do |encoded|
153+
decoded = Person.coder.load(encoded)
148154

149-
assert_nil decoded.id
150-
assert_not_predicate decoded, :persisted?
151-
assert_predicate decoded, :new_record?
155+
assert_nil decoded.id
156+
assert_not_predicate decoded, :persisted?
157+
assert_predicate decoded, :new_record?
158+
end
152159
ensure
153160
Person.primary_key = previous_value
154161
end
@@ -163,6 +170,14 @@ class SerializationTest < ActiveSupport::TestCase
163170
assert_raises(ArgumentError, match: "expected value to be Hash, but was Integer") { Person.coder.load(1) }
164171
end
165172

173+
test "#load does not remove a non-root key from a single-key Hash" do
174+
payload = { "friends" => [ { "id" => 1 } ] }
175+
176+
decoded = Person.coder.load(payload)
177+
178+
assert_equal [ 1 ], decoded.friends.map(&:id)
179+
end
180+
166181
test "#dump encodes resources" do
167182
resource = Person.new(id: 1, name: "Matz")
168183

0 commit comments

Comments
 (0)