roar-jsonapi icon indicating copy to clipboard operation
roar-jsonapi copied to clipboard

Representers: `defaults` block is lost in nested declarations

Open carlthuringer opened this issue 8 years ago • 3 comments

Complete Description of Issue

Due to legacy design, we want to use the non-strict behavior for as: for property-names, allowing underscores.

Following the Documentation I implemented a representer with the default set to strict: false.

require "roar/json"
require "roar/json/json_api"

class RuleRepresenter < Roar::Decorator
  include Roar::JSON::JSONAPI.resource :rules

  defaults do |name, _|
    { as: JSONAPI::MemberName.call(name, strict: false) }
  end

  attributes do
    property :chain_id
    property :name
    property :event_type
  end
end

However, the output was hyphenated!

[{:id=>"1c9c618a-86ad-437f-b3dd-50dd5a3e290f", :attributes=>{:"chain-id"=>"072bb8ca-a7c7-4408-b5f1-831d7277f676", :"event-type"=>"transactions"}, :type=>"rules"}]

I was able to workaround by changing my Representer. I placed the defaults block inside of the attributes block.

require "roar/json"
require "roar/json/json_api"

class RuleRepresenter < Roar::Decorator
  include Roar::JSON::JSONAPI.resource :rules

  attributes do
    defaults do |name, _|
      { as: JSONAPI::MemberName.call(name, strict: false) }
    end

    property :chain_id
    property :name
    property :event_type
  end
end

Steps to reproduce

Create a representer which sets a defaults block like so:

defaults do |name, _|
  { as: JSONAPI::MemberName.call(name, strict: false) }
end

and has attributes

attributes do
  property :name
end

Expected behavior

The attributes should be allowed to pass the non-strict conversion and remain underscored.

Actual behavior

Attributes are hyphenated.

System configuration

Roar version: 1.1.0 Roar JSONAPI version: 0.0.3 Declarative version: 0.0.9

During research, I found many things I didn't understand. Please excuse my ignorance.

  • attributes -> Roar::JSON::JSONAPI::Declarative, sets the inherit: true property, presumably so you can have multiple attributes blocks and they merge together.
  • nested -> When a block is passed, the options[:_base] is set to Decorator.default_nested_class, which is just an base Representable::Decorator. At this point, self is actually still RuleRepresenter.
  • Several steps omitted...
  • Declarative::Definitions::Definition#add Called with attributes, options and the block. Here it extracts some properties, calls the _defaults pipeline, and then calls the nested builder with the _base, name, and block.
  • Declarative::Schema::DSL::NestedBuilder (proc) is called, wherein self is Declarative::Schema::DSL. No context anymore here, except what was provided in options. which is provided for that purpose. This proc begins with Class.new(options[:_base]), which extends the Representable::Decorator supplied above. Then a block is evaluated which adds the features from the options context, and finally the block is class_evald. The evaluation of feature with the Roar::JSON::JSONAPI::Defaults feature sets up @options with a fresh set, and the options[:_defaults] from the parent is not used here. There's no way to set the options. There's no way to access the @dynamic_options block of options[:_defaults] either. I can't determine if there's some means by which to merge without hacking too much further.

Now, if you were to change Roar::JSON::JSONAPI::Declarative to pass the private option _defaults, then those configurations would be available inside of Declarative::Definitions::Definition#add. However, getting it merged inside of Declarative::Schema::DSL::NestedBuilder is beyond me at this time.

carlthuringer avatar Mar 07 '17 19:03 carlthuringer

@apotonick we should discuss making ::Declarative::Schema::DSL::NestedBuilder inherit defaults (same issue as https://github.com/trailblazer/roar/issues/173#issuecomment-161547989, #13)

myabc avatar Mar 07 '17 20:03 myabc

Is anyone looking into this? Is this gem still maintained?

Is there anyway to help solve this issue?

ghost avatar Apr 15 '19 15:04 ghost

Hey @myabc - any ideas?

Sorry @GustavoTango I am not maintaining this gem.

apotonick avatar Apr 16 '19 06:04 apotonick