[Proposal]: Allow `ActiveRecord::Relation` to store metadata that is retained as copies of it are created

Because of ActiveRecord::Relation’s laziness, the location where it (or one of its descendant copies created through methods like .where) is loaded (e.g. in a view) often differs from the location where it is created (e.g. in a controller, model, or service object).

This means features like Active Record Query Logs or tooling like Datadog’s tracing can give you clues but it’s up to you to work backwards and figure out where those queries came from on a case by case basis.

I would very much like a way to attach metadata to a relation

def returns_relation
  User.where(admin: true).metadata(service: "MyUserService")
end

and have this persist down the chain

child_relation = returns_relation.limit(10)
child_relation.metadata # => { service: "MyUserService" }

so that it can later be attached to database query spans or other instrumentation.


On first glance I think this would involve updates to

  • ActiveRecord::Relation to store this metadata
  • ActiveRecord::Relation::Merger#merge (source) to copy it over

and in theory spawn’s use of clone should ensure any copies created retain the metadata.


Happy to open a PR if a concrete implementation might be easier to evaluate, but wanted to gauge interest first.