Skip to content

Post-transfer hook guidance: AR callbacks are bypassed — what to do about search, caches, counter caches #40

Description

@sncalvo

Problem

The transfer is raw SQL, so AR callbacks don't fire. Users inadvertently ship code that silently skips:

  • Elasticsearch / OpenSearch / Algolia indexers
  • Counter cache increments
  • Russian-doll cache invalidation
  • touch: true associations

Each user rediscovers this the hard way.

Proposal

  • Dedicated README section: "Callbacks are bypassed — what you need to handle yourself"
  • Helper module StagingTable::Callbacks that can reindex/invalidate in bulk:
StagingTable.stage(User,
  after_transfer: ->(session, result) {
    User.where(id: result.inserted_ids + result.updated_ids)
        .find_in_batches { |batch| SearchIndexer.index_bulk(batch) }
  }
) { |s| s.insert(rows) }
  • Pairs with returning: so users have IDs to work with
  • Document the counter-cache recalculation pattern

Acceptance criteria

  • README section with the four classes of bypass + a recipe for each
  • Optional helper module (StagingTable::Callbacks.reset_counters, etc.)
  • Sample app / guide updated to include at least one of these

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions