Skip to content

expose_nil: conflicts with options passing to a block #378

Closed
@zverok

Description

@zverok

Minimum reproducible example:

class Test < Grape::Entity
  expose(:a, expose_nil: false) { |obj, options| options[:a] }
end

pp Test.new({}, a: 1).as_json # expected {a: 1}, renders {}
pp Test.new({}, a: nil).as_json # expected {}, renders {}

More debugging shows that block always returns nil, because when expose_nil: is present, the content of options inside block is changed completely; which this debugging serializer shows:

class Test < Grape::Entity
   expose(:a) { |obj, options| p(simple: options); options[:a] }
   expose(:b, as: :d) { |obj, options| p(with_as: options); obj[:a] }

   expose(:c, expose_nil: false) { |obj, options| p(with_expose_nil: options); options[:a] }
end

pp Test.new({}, a: 1, b: 2, c: 3).as_json

It prints this values for options inside blocks (and yes, in this order):

{:with_expose_nil=>{:expose_nil=>false, :proc=>#<Proc:0x0000555bb661d9a8 test_grape_expose.rb:52>}}
{:simple=>#<Grape::Entity::Options:0x0000555bb661c210 @opts_hash={:a=>1, :b=>2, :c=>3, :attr_path=>[:a]}, @has_only=false, @has_except=false, @for_nesting_cache={}, @should_return_key_cache={}>}
{:with_as=>#<Grape::Entity::Options:0x0000555bb661c210 @opts_hash={:a=>1, :b=>2, :c=>3, :attr_path=>[:d]}, @has_only=false, @has_except=false, @for_nesting_cache={}, @should_return_key_cache={}>}

It seems that block in this case receives "options passed to expose DSL" instead of "options passed to serialization"?..

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions