Skip to content

Conversation

@dimitrikochnev
Copy link

Motivation

When importing objects, the data needed for indexing (e.g., embeddings, computed attributes) is often already available in memory at the call site. However, currently, crutch blocks are forced to re-fetch (even with direct_import) this data from the database, resulting in redundant queries and wasted resources.

There is currently no mechanism to pass this pre-computed data from the import call site down into crutch blocks or field value procs.

This design aligns with established patterns in the Ruby ecosystem, such as graphql-ruby and ActiveModelSerializers. In those libraries, a context object is similarly passed through the resolution or serialization stack to share request-level state (like current user, auth tokens, or pre-loaded data) without relying on global state.

Solution

Add an optional context: keyword argument to import/import! that flows through the entire indexing pipeline. Context is an arbitrary hash, defaulting to {}.

# Pass pre-computed data to avoid redundant DB queries
MyIndex.import!(objects, context: { embeddings: precomputed_embeddings })

Context in crutch blocks (2nd argument)

crutch :embeddings do |collection, context|
  # Use pre-computed data if available, otherwise fetch from DB
  context[:embeddings] || load_embeddings(collection)
end

Context in field value procs (3rd argument)

field :embedding, value: ->(object, crutches, context) {
  context[:override] || crutches.embeddings[object.id]
}

Both are fully backward-compatible — existing 1-arg crutch blocks and 1-2 arg field procs continue to work unchanged via arity-based dispatch.

@dimitrikochnev dimitrikochnev requested a review from a team as a code owner January 29, 2026 11:47
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.

1 participant