Open sandstrom opened 8 months ago
Happy to discuss this in more detail, and elaborate more.
Friendly ping @lessthanjacob @njbbaer @ritikesh
If you think this is a reasonable suggestion, let me know! If so, I'd propose these steps:
For reference, there are also a few other issues that I've opened, where I'd also be happy to get your input.
I think this would be a reasonable refactor.
@njbbaer @ritikesh any thoughts/concerns here?
Agreed, we are open to contributions @sandstrom.
@lessthanjacob @ritikesh Thanks!
I'll have a chat with a colleague of mine, and we'll try to get back with a proposal.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Still relevant!
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Not stale
I've been experimenting with this V2 extractor in #479. I think it covers the concerns in this issue.
Note that V2 (currently - nothing is set in stone) makes a distinction between a has_one/belongs_to association (aka object
) and a has_many (aka collection
). Those terms may change, but the distinction is proving useful in several areas.
module Blueprinter
module V2
# The default extractor and base class for custom extractors
class Extractor
#
# Extract a field value.
#
# @param ctx [Blueprinter::V2::Context]
#
def field(ctx)
if ctx.field.value_proc
ctx.blueprint.instance_exec(ctx.object, ctx.options, &ctx.field.value_proc)
elsif ctx.object.is_a? Hash
ctx.object[ctx.field.from]
else
ctx.object.public_send(ctx.field.from)
end
end
#
# Extract an object field (singular association) value.
#
# @param ctx [Blueprinter::V2::Context]
#
def object(ctx)
field ctx
end
#
# Extract a collection field (array of objects) value.
#
# @param ctx [Blueprinter::V2::Context]
#
def collection(ctx)
field ctx
end
end
end
end
I think it looks good!
I would consider a name other than object
for the singular association. Maybe has_one/has_many
, single_item/multiple_items
, item/collection
, element/collection
.
The things we've done in our extractors are:
I think those would be covered here.
Any code example of what context would be?
@sandstrom Again, this is very much a WIP, but context
is currently defined in #479 as:
#
# The Context struct is used for most extension hooks and all extractor methods.
# Some fields are always present, others are context-dependant. Each hook and extractor
# method will separately document which fields to expect and any special meanings.
#
# blueprint = Instance of the current Blueprint class (always)
# field = Field | ObjectField | Collection (optional)
# value = The current value of `field` or the Blueprint output (optional)
# object = The object currently being evaluated (e.g. passed to `render` or from an association) (optional)
# options = Arbitrary options passed to `render` (always)
# instances = Allows this entire render to share instances of Blueprints and Extractors (always)
# data = A Hash to for extensions, etc to cache render data in (always)
#
Context = Struct.new(:blueprint, :field, :value, :object, :options, :instances, :data)
Is there an existing issue for this?
Is your feature request related to a problem? Please describe
Association extractor is useful to modify to e.g. add a circuit-breaker, implement caching and for a few other things. Right now it's somewhat complicated to override/modify.
Describe the feature you'd like to see implemented
Right now, there are two types of extractors: AssociationExtractor and AutoExtractor (along with some sub-extractors).
Their roles are somewhat intertwined (AssociationExtractor calls the AutoExtractor, for example), and only one of them can be modified globally.
I'd propose a stricter separation, splitting it up into (probably) three extractors:
The default
ValueExtractor
would encapsulate the logic currently existing in AutoExtractor, and I'd move the logic of deferring to block to field/association extractors.ValueExtractor
could also be named something likeDataExtractor
instead.Example
This is a rough sketch, in reality it would probably be slightly different.
Describe alternatives you've considered
No response
Additional context
No response