[With PR][Feature Request] Discard blank attribute
PR: https://github.com/procore-oss/blueprinter/pull/425
Is there an existing issue for this?
- [X] I have searched the existing issues
Is your feature request related to a problem? Please describe
I can talk about my specific use case scenario. I'm using Blueprinter in a Ruby on Rails application. I have created an ApplicationBlueprint that extends Blueprinter::Base and I make all my blueprints extends from that class. It's pretty much the same pattern we use for ActiveRecord or Controllers or ApplicationJob, etc.
For my form validations, I always include in my output an errors field for every record or associations.
Exemple of output
{
id: 1,
name: null,
errors: { name: ["can't be blank"] }
cars: [
{ id: 1, name: "My super fast car", year: null, errors: [{year: ["can't be blank"}] }
]
}
This is done in my ApplicationBlueprint which all my blueprint extends of. A very important note here is that in Rails, calling user.errors will give me all errors of user but also includes all the ones from cars. In this payload, I only have interest in the error of the same 'level' i'm currently blueprinting. In order to do that, I simply reject all errors that contains a dot so my user error are basically this { "name": [...], "cars.year": [...] }.reject(...all attribute with dot)
field(:errors) do |record|
record.try(:errors)&.as_json&.reject { |attribute| attribute.to_s.include?(".") }.presence
end
Describe the feature you'd like to see implemented
If there are no errors in a record or I am rendering something that doesn't even implement errors as a method, I would like to not render the field at all. I understand there is already a "similar" feature implemented:
if = ->(field_name, obj, _options) { true || false }
however this would force me to compute twice the value of the field to know if I should render it or not like so:
field(:errors, if: ->((_, obj, __) { obj.try(:errors)&.as_json&.reject { |attribute| attribute.to_s.include?(".") }.present? } ) do |record|
record.try(:errors)&.as_json&.reject { |attribute| attribute.to_s.include?(".") }.presence
end
What I would like:
field(:errors, discard_nil: true) do |record|
record.try(:errors)&.as_json&.reject { |attribute| attribute.to_s.include?(".") }.presence
end