Skip to content

Add support for autoloading nested related objects on ingredients - #72

Open
mamhoff wants to merge 7 commits into
mainfrom
better-autoloading
Open

Add support for autoloading nested related objects on ingredients#72
mamhoff wants to merge 7 commits into
mainfrom
better-autoloading

Conversation

@mamhoff

@mamhoff mamhoff commented Jul 19, 2023

Copy link
Copy Markdown
Contributor

This takes the capabilities from AlchemyCMS/alchemy_cms#2523 and allows pre-loading object graphs on ingredient's related objects.

@tvdeyen tvdeyen left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice. I think the specs fail because we now always return public version elements.

Comment thread app/controllers/alchemy/json_api/pages_controller.rb Outdated
Comment thread app/serializers/alchemy/json_api/page_serializer.rb Outdated

@tvdeyen tvdeyen left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @mamhoff still want to work on this?

Comment thread app/controllers/alchemy/json_api/pages_controller.rb
Comment thread app/controllers/alchemy/json_api/pages_controller.rb Outdated
mamhoff and others added 7 commits September 4, 2026 12:05
This adds a `.preload_relations` object to serializers and leverages
that and the Rails preloader service object to preload ActiveRecord
object graphs below the related object of ingredients.
The pagination fixes imported from the jsonapi.rb PR left spaces inside
the hash literal braces, tripping Standard's Layout/SpaceInsideHashLiteralBraces
cop and blocking CI. Remove them to match the project's lint config.
Guard the serializer lookup with safe_constantize so an ingredient type
without a matching JSON:API serializer is skipped rather than raising a
NameError during preloading. Also drop the Rails 6 Preloader fallback,
which is dead code since the gem requires alchemy_cms >= 8.2, and that in
turn requires Rails 7.2 or newer.
The jsonapi_paginate and jsonapi_pagination_meta overrides were a
workaround for jsonapi.rb losing the pre-pagination total when the
collection is decorated after pagination (the pages controller maps the
paginated result into api_page objects). That was fixed upstream by
stas/jsonapi.rb#91, first released in jsonapi.rb 2.1.1, whose
implementation is now identical to the overrides. Require >= 2.1.1 so the
fix is guaranteed to be present and remove the redundant code.
The picture serializer hard-coded `preload_relations => [:thumbs]`, but
`Alchemy::Picture` only defines the `thumbs` association under the Dragonfly
storage adapter. On the default ActiveStorage adapter that association does
not exist, so serializing a picture ingredient with a picture attached raised
`ActiveRecord::AssociationNotFoundError` and returned a 500 for any request
including ingredients. No spec attached a real picture, so the suite missed it.

Instead of naming associations per serializer, ask each related object class to
preload its own storage-specific associations through Alchemy's
`alchemy_element_preloads` hook (the same mechanism core's ElementPreloader
uses), which resolves to the correct associations for the active storage
adapter and works for any relatable resource. This removes the `preload_relations`
serializer API entirely.
Ingredient relationships are lazy-loaded, so their linkage and resources are
only emitted when the request's `include` asks for them. The scope, however,
eager loaded `{ingredients: :related_object}` on every request, materialising
ingredients and their related objects even for requests that never serialize
them. Gate that eager load (and the matching related-object preload) on the
same `include_ingredients?` predicate so both stay in sync and nothing is
fetched needlessly. The element tree stays eager because its linkage is always
present.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants