-
Notifications
You must be signed in to change notification settings - Fork 94
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[FEATURE] Add a method for handling expansion of child objects in jbuilder #962
Comments
@clarissalimab can I have a review of this with any feedback? |
Thanks for submitting your first issue to Houdini! |
I think it's a very good solution! Just to make sure I understand correctly, each |
Thanks @github-actions, I'm eager to be involved in such an exciting project. 😆 |
Oops, yes! So the various jbuilder templates would be: # app/views/api/transactions/_transactions.json.jbuilder
json.(transaction, :id)
json.created transaction.created.to_i
handle_expansion(:supporter, transaction.supporter, {json:json, __expand:__expand})
handle_expansion(:subtransaction, transaction.subtransaction, {json:json, __expand: __expand})
# app/views/api/subtransactions/_subtransactions.json.jbuilder
json.(subtransaction, :id)
json.created subtransaction.created.to_i
handle_expansion(:transaction, subtransaction.trx, {json:json, __expand:__expand})
handle_expansion(:supporter, subtransaction.supporter, {json:json, __expand:__expand})
handle_array_expansion(:payments, subtransaction.subtransaction_payments, {json:json, __expand:__expand}) do |payment, opts|
handle_item_expansion(payment, {json:opts.json, as: opts.item_as, __expand: opts.__expand})
end |
Makes a lot of sense to me, I like it. Excellent design! |
Hi @wwahammy, @MaiconMares and I will be working on this issue. |
Hi there @alan-ms, This work is actually sort of completed in https://github.com/CommitChange/houdini/tree/webhooks but it's a pretty complex task. Please look into how its implemented there and reuse it as much as possible. |
Hi @wwahammy. We've looked into the solution implemented, but we are a bit confused about what is not finished and we need to implement. |
Currently, there's no way to expand child objects in jbuilder files. Ultimately, we should be able to do this. As an example, look at the following (simplified) transaction object for:
A user may instead want the subtransaction expanded so they don't have to make a second request:
As user may want the supporter and the subtransaction expanded both:
Additionally, a user may want the subtransaction payments expanded, but now the supporter:
A proposed solution
We should be able to pass an object describing the expansions to a call to render a jbuilder partial. I'll explain the object description and how the call should be used.
Expansion descriptions
I believe a simple mechanism for expansion descriptions would be to provide an array that has the dot paths to parts of the JSON to expand from the root element. Here are the expansions for each of examples:
Passing to a jbuilder template
From the level of the controller, you can pass the expansions by setting the
@__expand
variable. (Named like this to avoid any sort of collisions with something named@expand
). Let's show how this would look inTransactionController
if we always want to expand the supporter.Sanitizing expansion requests
We usually want to allow an API user to provide the specific expansions they want. On a transaction object, users may want supporter expanded while others may want the subtransaction expanded. To that end, we can have the user send a parameter named
__expand
which contains an array of dot paths to expand.We probably should not allow an unlimited set of expansions, at least for all users. A user could request a really large set of expansions which might make the requests go slowly and overload the server. For example, let's say from the transaction element, request a super long expansion like:
subtransaction.subtransaction_payments.transaction.subtransaction.subtransaction_payments.transaction.subtransaction.subtransaction_payments.transaction.subtransaction.subtransaction_payments.transaction.subtransaction.subtransaction_payments.transaction.subtransaction.subtransaction_payments.transaction.subtransaction.subtransaction_payments.transaction.subtransaction.subtransaction_payments.transaction.subtransaction.subtransaction_payments.transaction.subtransaction.subtransaction_payments.transaction.subtransaction.subtransaction_payments.transaction
. That's a valid expansion but it's pointlessly long. Therefore, we should likely prevent an average user from expanding more than one level deep (perhaps super_admins could have more?).We would create a method for controllers called
sanitized_expansions
which would:params['__expand']
into an containing the dot path to be expanded. This will also remove duplicates, for example. If they request:["supporter", "subtransaction", "subtransaction.subtransaction_payments"]
, they'll get an object representing a tree that looks, more or less, like this:It would then could be used as follows:
passing from a template to a partial
Once you're in a jbuilder template, you need to pass the expansions to a partial, you can use it like shown in the
app/views/api/transactions/show.json.jbuilder
passing between partials
Once in a partial, you can add use the
handle_expansion
helper method (maybe a better name exists?) like shown in in this exampleapp/views/api/transactions/_transactions.json.jbuilder
handle_expansion
here accepts:supporter
__expand
variable (we might be able to get this automatically)If
__expand
is not set to expand supporter, this is the equivalent of:if
__expand
is set to expand supporter, this is the equivalent of:For array elements, we use the
handle_array_expansion
andhandle_item_expansion
methods. Let's assume we're in thesubtransaction
partial now and this is forsubtransaction_payments
. we would use it as follows:handle_array_expansion
here accepts:the attribute name, in this case
payments
the object decide on how to expand, in this case
subtransaction.subtransaction_payments
as hash with:
__expand
variable (we might be able to get this automatically)item_as
: the name of the variable for passing the item intohandle_item_expansion
a block for displaying the item which has two parameters:
json
: the jbuilder object__expand
: which is the result of__expand.children_of(attribute_name)
as passed into the objectas
: the name of the variable when passed into a partial for jsonhandle_item_expansion
accepts:json
: the jbuilder objectas
: the name of the variable when passed into a partial__expand
: the expand variable for what can be expanded in the partialResult
If payments is not supposed to be expanded, this is the equivalent of:
If payments is supposed to be expanded this is the equivalent of:
If
payments.supporter
is supposed to be expanded, this is the equivalent of:The text was updated successfully, but these errors were encountered: