diff --git a/README.md b/README.md index d5c7243a..98cf9d85 100644 --- a/README.md +++ b/README.md @@ -694,6 +694,36 @@ _NOTE:_ The field-level setting overrides the global config setting (for the fie +
+Exclude Fields with nil Values + + +By default, fields with `nil` values are included when rendering. You can override this behavior by setting `:exclude_if_nil: true` in the field definition. + +Usage: + +```ruby +class UserBlueprint < Blueprinter::Base + identifier :uuid + + field :name + field :birthday, exclude_if_nil: true +end + +user = User.new(name: 'John Doe') +puts UserBlueprint.render(user) +``` + +Output: + +```json +{ + "name": "John Doe" +} +``` + +
+
Custom Formatting for Dates and Times diff --git a/lib/blueprinter/helpers/base_helpers.rb b/lib/blueprinter/helpers/base_helpers.rb index 3c083219..79079254 100644 --- a/lib/blueprinter/helpers/base_helpers.rb +++ b/lib/blueprinter/helpers/base_helpers.rb @@ -48,7 +48,11 @@ def object_to_hash(object, view_name:, local_options:) result_hash = view_collection.fields_for(view_name).each_with_object({}) do |field, hash| next if field.skip?(field.name, object, local_options) - hash[field.name] = field.extract(object, local_options) + value = field.extract(object, local_options) + + next if value.nil? && field.options[:exclude_if_nil] + + hash[field.name] = value end view_collection.transformers(view_name).each do |transformer| transformer.transform(result_hash, object, local_options) diff --git a/spec/integrations/base_spec.rb b/spec/integrations/base_spec.rb index 80d26564..7eb95f98 100644 --- a/spec/integrations/base_spec.rb +++ b/spec/integrations/base_spec.rb @@ -82,6 +82,32 @@ end end + context 'Given exclude_if_nil is passed' do + let(:obj) { OpenStruct.new(obj_hash.merge(category: nil, label: 'not nil')) } + + context 'and exclude_if_nil is true' do + let(:blueprint) do + Class.new(Blueprinter::Base) do + field :category, exclude_if_nil: true + field :label, exclude_if_nil: true + end + end + let(:result) { '{"label":"not nil"}' } + it { expect(blueprint.render(obj)).to eq(result) } + end + + context 'and exclude_if_nil is false' do + let(:blueprint) do + Class.new(Blueprinter::Base) do + field :category, exclude_if_nil: false + field :label, exclude_if_nil: true + end + end + let(:result) { '{"category":null,"label":"not nil"}' } + it { expect(blueprint.render(obj)).to eq(result) } + end + end + context 'Inside Rails project' do include FactoryBot::Syntax::Methods let(:obj) { create(:user) }