From d4529693d85416d000c161597d07718e0a736188 Mon Sep 17 00:00:00 2001 From: Kevin Date: Thu, 23 Nov 2023 23:01:40 +0700 Subject: [PATCH] chore/handle_key_not_found- chore: support render unless key not found --- README.md | 3 +++ lib/simple_representer/field.rb | 5 +++++ .../simple_representer/definable_spec.rb | 5 +++-- .../simple_representer/property_spec.rb | 22 +++++++++++++++++++ .../simple_representer/representer_spec.rb | 1 + 5 files changed, 34 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8da1ace..2e2280a 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,9 @@ property :name, default: 'Paladin' - `render_nil` to render or skip nil value (default is false): ```ruby # will render { name: nil } if name is nil +``` +- `render_if_key_found` to render or skip if key not found (default is false): +```ruby property :name, render_nil: true ``` - `representer` to use different representer for nested objects. diff --git a/lib/simple_representer/field.rb b/lib/simple_representer/field.rb index f04ebc0..d43cbc5 100644 --- a/lib/simple_representer/field.rb +++ b/lib/simple_representer/field.rb @@ -10,6 +10,8 @@ def initialize(field, options) end def call(representer) + @representer = representer + return if options[:if] && !representer.instance_exec(&options[:if]) value = process(representer) @@ -21,6 +23,8 @@ def call(representer) private + attr_reader :representer + def nested_representer(value) return options[:representer].for_collection(value).to_h if value.is_a?(Array) @@ -29,6 +33,7 @@ def nested_representer(value) def build_field(value) return if value.nil? && !options.fetch(:render_nil, false) + return if value.nil? && options.fetch(:render_if_key_found, false) && !representer.represented.respond_to?(field) [(options[:as] || field).to_sym, value] end diff --git a/spec/simple_representer/simple_representer/definable_spec.rb b/spec/simple_representer/simple_representer/definable_spec.rb index d513fe6..4296c6a 100644 --- a/spec/simple_representer/simple_representer/definable_spec.rb +++ b/spec/simple_representer/simple_representer/definable_spec.rb @@ -6,6 +6,7 @@ class Test include SimpleRepresenter::Definable defaults render_nil: true + defaults render_if_key_found: true property :name, if: -> { true } computed :id, as: :uid @@ -17,9 +18,9 @@ class Test expect(subject.size).to eq(2) expect(subject[0]).to be_kind_of(SimpleRepresenter::Property) expect(subject[0].field).to eq(:name) - expect(subject[0].options.keys).to include(:if, :render_nil) + expect(subject[0].options.keys).to include(:if, :render_nil, :render_if_key_found) expect(subject[1]).to be_kind_of(SimpleRepresenter::Computed) expect(subject[1].field).to eq(:id) - expect(subject[1].options).to eq({ as: :uid, render_nil: true }) + expect(subject[1].options).to eq({ as: :uid, render_nil: true, render_if_key_found: true }) end end diff --git a/spec/simple_representer/simple_representer/property_spec.rb b/spec/simple_representer/simple_representer/property_spec.rb index a84885a..f0c37fc 100644 --- a/spec/simple_representer/simple_representer/property_spec.rb +++ b/spec/simple_representer/simple_representer/property_spec.rb @@ -1,4 +1,5 @@ require 'spec_helper' +require_relative '../../../lib/simple_representer/representer' require_relative '../../../lib/simple_representer/property' RSpec.describe SimpleRepresenter::Property do @@ -85,4 +86,25 @@ class NestedRepresenter < SimpleRepresenter::Representer it { is_expected.to eq([:name, nil]) } end end + + context 'with render_if_key_found option' do + let(:representer) { double({ represented: OpenStruct.new(name: 'Paladin') }) } + + context 'should render field if key is found by default' do + let(:options) { {} } + it { is_expected.to eq([:name, 'Paladin']) } + end + + context 'should not render field if render_if_key_found is true' do + let(:representer) { double({ represented: OpenStruct.new(inside_name: 'Paladin') }) } + let(:options) { { render_if_key_found: true, render_nil: true } } + it { is_expected.to eq(nil) } + end + + context 'should render field if render_if_key_found is false' do + let(:representer) { double({ represented: OpenStruct.new(inside_name: 'Paladin') }) } + let(:options) { { render_if_key_found: false, render_nil: true } } + it { is_expected.to eq([:name, nil]) } + end + end end diff --git a/spec/simple_representer/simple_representer/representer_spec.rb b/spec/simple_representer/simple_representer/representer_spec.rb index 2243560..1cb7a5e 100644 --- a/spec/simple_representer/simple_representer/representer_spec.rb +++ b/spec/simple_representer/simple_representer/representer_spec.rb @@ -5,6 +5,7 @@ RSpec.describe SimpleRepresenter::Representer do class CompanyRepresenter < SimpleRepresenter::Representer defaults render_nil: true + defaults render_if_key_found: false property :name end