kgiszczak / shale

Shale is a Ruby object mapper and serializer for JSON, YAML, TOML, CSV and XML. It allows you to parse JSON, YAML, TOML, CSV and XML data and convert it into Ruby data structures, as well as serialize data structures into JSON, YAML, TOML, CSV or XML.
https://shalerb.org/
MIT License
618 stars 19 forks source link

JSON map attributes are ignored when calling `as_json` #34

Closed BoboFraggins closed 3 months ago

BoboFraggins commented 3 months ago

Given the following mapper:

class Test < Shale::Mapper
  attribute :nil_attribute, Shale::Type::String
  attribute :rails_attribute_name, Shale::Type::String

  json do
    map 'nil_attribute', to: :nil_attribute, render_nil: true
    map 'json_attribute_name', to: :rails_attribute_name
  end
end

I would expect both of these calls to generate the same hash:

irb(main):004> JSON.parse(Test.new(rails_attribute_name: 'foobar').to_json)
=> {"nil_attribute"=>nil, "json_attribute_name"=>"foobar"}
irb(main):003> Test.new(rails_attribute_name: 'foobar').as_json
=> {"rails_attribute_name"=>"foobar"}

But as_json ignores the attribute name change and the render_nil option.

I am happy to take a crack at fixing this, but before trying to I wanted to confirm that you believe this is a bug.

kgiszczak commented 3 months ago

Shale doesn't provide as_json method on an object instance. This method is only available on a class level e.g Test.as_json(Test.new).

I think some other library might bleed into your objects (e.g Rails).

Here's an example showing that everything works correctly:

class Test < Shale::Mapper
  attribute :nil_attribute, Shale::Type::String
  attribute :rails_attribute_name, Shale::Type::String

  json do
    map 'nil_attribute', to: :nil_attribute, render_nil: true
    map 'json_attribute_name', to: :rails_attribute_name
  end
end

puts Test.to_json(Test.new)
puts Test.as_json(Test.new)

The output is this:

{"nil_attribute":null}
{"nil_attribute"=>nil}
BoboFraggins commented 3 months ago

Gotcha. Thanks for the response, love the gem!