Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Child removes node from response when the provided object is an empty array #725

Open
Kinaan opened this issue May 27, 2019 · 2 comments
Open

Comments

@Kinaan
Copy link

Kinaan commented May 27, 2019

I have 2 different rabl templates and their actual outputs are provided below.

File 1: test.rabl

object false

child @test_objects => :test_objects do
  attribute :object_id
end

node(false) do
  node(:total)   { 10 }
  node(:pages)   { 10 }
  node(:page_no) { 1 }
end

This works as expected

> puts Rabl::Renderer.new('test', nil, format: :json, locals: { test_objects: [OpenStruct.new] }).render
{"test_objects":[{"test_object":{"object_id":70186699097320}}],"total":10,"pages":10,"page_no":1}

## With test_objects as empty array 
> puts Rabl::Renderer.new('test', nil, format: :json, locals: { test_objects: [] }).render
{"test_objects":[],"total":10,"pages":10,"page_no":1}

File 2: test2.rabl

object false

child @test_objects, :root => :test_objects, :object_root => false do
  attribute :object_id
end

node(false) do
  node(:total)   { 10 }
  node(:pages)   { 10 }
  node(:page_no) { 1 }
end

The issue occurs when @test_objects is an empty array (2nd case). The test_objects attribute doesn't make it to the final response.

> puts Rabl::Renderer.new('test2', nil, format: :json, locals: { test_objects: [OpenStruct.new] }).render
{"test_objects":[{"object_id":70186677972660}],"total":10,"pages":10,"page_no":1}

## With test_objects as empty array 
> puts Rabl::Renderer.new('test2', nil, format: :json, locals: { test_objects: [] }).render
{"total":10,"pages":10,"page_no":1}

The only work around / hack that seems to work is if we change the definition of child block to something like this

child({@test_objects => :test_objects}, {:root => :test_objects, :object_root => false}) do

In case this is accepted as a bug, the line that causes this behavior is here
https://github.com/nesquena/rabl/blob/master/lib/rabl/builder.rb#L171

When first argument is hash (with empty array as the value), the data.present? won't fail. This behavior is different obviously as it fails when empty array is passed as first argument.

I found that this check was introduced around 8 years back and I am not sure if it should be removed or not, so filing issue to discuss a better way to handle this scenario.

@Kinaan
Copy link
Author

Kinaan commented Jun 12, 2019

Anyone ? 🙂

@caifara
Copy link

caifara commented Nov 26, 2021

The same problem occurs when a child is defined, but the given object ends up to be nil: the key will not be present in the response because of the early return mentioned above.

My suggestion would be to omit the key when the condition is not met (second branch of the conditional mentioned above). If the condition is met, an empty array or null value is returned if necessary.

Another - backward compatible solution - would be to allow a default value. (Although we would prefer a change as it makes an api more predictable and adds less burden on the developer who may forget to add a default on every child).

I can submit a PR if you want such a change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants