From 8eb614ec66eac51732c200bdb2890a4bec7578c8 Mon Sep 17 00:00:00 2001 From: Konstantin Munteanu Date: Thu, 30 Oct 2025 10:55:50 +0100 Subject: [PATCH 1/2] Allow underscore navigation --- .rubocop.yml | 5 +++++ lib/ja2r/element.rb | 37 ++++++++++++++++++++++++++++--------- spec/fixtures/singular.json | 13 +++++++++++++ spec/ja2r/element_spec.rb | 26 ++++++++++++++++++++++++++ spec/ja2r_spec.rb | 1 + 5 files changed, 73 insertions(+), 9 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 451eecf..62e7e41 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -10,6 +10,11 @@ Layout/SpaceInsideHashLiteralBraces: Lint/AssignmentInCondition: Enabled: false +Metrics/CyclomaticComplexity: + Max: 9 +Metrics/PerceivedComplexity: + Max: 9 + Style/ClassAndModuleChildren: Enabled: false Style/ConditionalAssignment: diff --git a/lib/ja2r/element.rb b/lib/ja2r/element.rb index b54ca8d..639aaf5 100644 --- a/lib/ja2r/element.rb +++ b/lib/ja2r/element.rb @@ -3,7 +3,8 @@ class Element def initialize(origin_data, options = {}) @origin_data = origin_data.with_indifferent_access @options = options - @relationships = origin_data['relationships'] ? convert_relationships(origin_data['relationships']) : {} + @relationships = origin_data['relationships']&.then { |rd| convert_relationships(rd) } || {} + build_references end attr_reader :origin_data, :relationships @@ -39,18 +40,36 @@ def type private - def method_missing(symbol, *args) - return attributes[symbol] if attributes&.key? symbol - return relationships[symbol] if relationships&.key? symbol + def build_references + @references = {}.with_indifferent_access + attributes&.each_key do |key| + @references[key] ||= {attribute: key} + @references[key.underscore] ||= {attribute: key} + end + relationships&.each_key do |key| + @references[key] ||= {relationship: key} + @references[key.underscore] ||= {relationship: key} + end + end - safe_traverse? ? nil : super + def method_missing(symbol, *args) + case @references[symbol] + in attribute: + attributes[attribute] + in relationship: + relationships[relationship] + else + safe_traverse? ? nil : super + end end def respond_to_missing?(symbol, include_all = false) - return true if attributes&.key?(symbol) - return true if relationships&.key?(symbol) - - safe_traverse? || super + if @references.key? symbol + true + else + safe_traverse? || super + safe_traverse? ? true : super + end end def safe_traverse? diff --git a/spec/fixtures/singular.json b/spec/fixtures/singular.json index fa1661c..59acf2a 100644 --- a/spec/fixtures/singular.json +++ b/spec/fixtures/singular.json @@ -12,6 +12,12 @@ "example": true }, "relationships":{ + "best-friend":{ + "data":{ + "id":"1005", + "type":"persons" + } + }, "sister":{ "data":{ "id":"1002", @@ -34,6 +40,13 @@ "name":"Lisa" } }, + { + "id":"1005", + "type":"persons", + "attributes":{ + "name":"Milhouse" + } + }, { "id":"998", "type":"persons", diff --git a/spec/ja2r/element_spec.rb b/spec/ja2r/element_spec.rb index 242d4a9..61d9785 100644 --- a/spec/ja2r/element_spec.rb +++ b/spec/ja2r/element_spec.rb @@ -43,4 +43,30 @@ end end end + + context 'with dashes in the keys' do + let(:origin_data) do + { + 'id' => 'some-id', + 'attributes' => { + 'foo-field' => 'foo-value', + 'bar-field' => { + 'bar-value' => true + } + }, + 'relationships' => { + 'some-one' => { + 'data' => {'id' => '1122', 'type' => 'some-ones'} + } + } + } + end + + it 'allows navigation with underscore' do + expect(element.foo_field).to eq 'foo-value' + expect(element.bar_field).to eq('bar-value' => true) + expect(element.some_one).to be_a(described_class) + expect(element.some_one.type).to eq('some-ones') + end + end end diff --git a/spec/ja2r_spec.rb b/spec/ja2r_spec.rb index 7cca268..cc48abe 100644 --- a/spec/ja2r_spec.rb +++ b/spec/ja2r_spec.rb @@ -5,6 +5,7 @@ it 'can handle singular relations' do ele = described_class.parse payload expect(ele.id).to eq '1001' + expect(ele.best_friend.name).to eq 'Milhouse' expect(ele.sister.id).to eq '1002' expect(ele.sister.name).to eq 'Lisa' expect(ele.father.id).to eq '998' From bca960557e540bed0a1011dc6e4b782b5be5739b Mon Sep 17 00:00:00 2001 From: Konstantin Munteanu Date: Thu, 30 Oct 2025 11:09:32 +0100 Subject: [PATCH 2/2] rubocop --- lib/ja2r/element.rb | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/lib/ja2r/element.rb b/lib/ja2r/element.rb index 639aaf5..4e58cf3 100644 --- a/lib/ja2r/element.rb +++ b/lib/ja2r/element.rb @@ -47,8 +47,8 @@ def build_references @references[key.underscore] ||= {attribute: key} end relationships&.each_key do |key| - @references[key] ||= {relationship: key} - @references[key.underscore] ||= {relationship: key} + @references[key] ||= {relationship: key} + @references[key.underscore] ||= {relationship: key} end end @@ -64,12 +64,7 @@ def method_missing(symbol, *args) end def respond_to_missing?(symbol, include_all = false) - if @references.key? symbol - true - else - safe_traverse? || super - safe_traverse? ? true : super - end + @references.key?(symbol) || safe_traverse? || super end def safe_traverse?