Skip to content

Commit 04149be

Browse files
committed
Grape::Entity#serializable_hash should call #serializable_hash elementwise if the data returned from #value_for is an array for which each element responds to that method so that nested Grape::Entity presentation works correctly with arrays of values.
1 parent a1de0e2 commit 04149be

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

lib/grape/entity.rb

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,8 +233,15 @@ def serializable_hash(runtime_options = {})
233233
opts = options.merge(runtime_options || {})
234234
exposures.inject({}) do |output, (attribute, exposure_options)|
235235
partial_output = value_for(attribute, opts) if conditions_met?(exposure_options, opts)
236-
partial_output = partial_output.serializable_hash(runtime_options) if partial_output.respond_to? :serializable_hash
237-
output[key_for(attribute)] = partial_output
236+
237+
output[key_for(attribute)] =
238+
if partial_output.respond_to? :serializable_hash
239+
partial_output.serializable_hash(runtime_options)
240+
elsif partial_output.kind_of?(Array) && !partial_output.map {|o| o.respond_to? :serializable_hash}.include?(false)
241+
partial_output.map {|o| o.serializable_hash}
242+
else
243+
partial_output
244+
end
238245

239246
output
240247
end

spec/grape/entity_spec.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,28 @@ def embedded
279279
presenter = fresh_class.new(SimpleExample.new)
280280
presenter.serializable_hash.should == {:name => "abc", :embedded => {:abc => "def"}}
281281
end
282+
283+
it 'should serialize embedded arrays of objects which respond to #serializable_hash' do
284+
class EmbeddedExample
285+
def serializable_hash(opts = {})
286+
{:abc => 'def'}
287+
end
288+
end
289+
290+
class SimpleExample
291+
def name
292+
"abc"
293+
end
294+
295+
def embedded
296+
[EmbeddedExample.new, EmbeddedExample.new]
297+
end
298+
end
299+
300+
fresh_class.expose :name, :embedded
301+
presenter = fresh_class.new(SimpleExample.new)
302+
presenter.serializable_hash.should == {:name => "abc", :embedded => [{:abc => "def"}, {:abc => "def"}]}
303+
end
282304
end
283305

284306
describe '#value_for' do

0 commit comments

Comments
 (0)