module

Ralph::IdentityMap

Per-request identity map for loaded models

The identity map ensures that within a given scope, loading the same record multiple times returns the same object instance. This:

  • Prevents duplicate objects for the same database record
  • Reduces memory usage when the same records are accessed repeatedly
  • Ensures consistency when modifying objects

Usage

The identity map is scoped to a block using IdentityMap.with:

Ralph::IdentityMap.with do
  user1 = User.find(1)
  user2 = User.find(1)               # Returns same instance from identity map
  user1.object_id == user2.object_id # => true

  # Changes to one reference affect all references
  user1.name = "New Name"
  user2.name # => "New Name"
end

Web Framework Integration

In web frameworks, you typically enable the identity map for each request:

# In a before_action or middleware
Ralph::IdentityMap.with do
  # Handle request...
  call_next(context)
end

Thread Safety

The identity map uses fiber-local storage, so each fiber/request has its own isolated identity map. This is safe for concurrent requests.

Caveats

  • The identity map only works within the scope of IdentityMap.with
  • Outside this scope, each query returns new model instances
  • Be careful with long-running identity maps as they can accumulate memory
  • Call IdentityMap.clear to manually clear the map within a scope

Class methods

all(model_class : T.class) : Array(T) forall T

Get all models of a specific class from the identity map

Source
clear

Clear all entries from the current identity map

Use this to free memory or to ensure fresh data is loaded.

Source
enabled?

Check if an identity map is currently active

Source
get(model_class : T.class, id) : T | Nil forall T

Get a model from the identity map

Returns the cached model if found, nil otherwise. This is called automatically by Model.find and similar methods.

Source
has?(model_class : T.class, id) : Bool forall T

Check if a specific model is in the identity map

Source
remove(model_class : T.class, id) : Nil forall T

Remove a model by class and id

Source
remove(model : Model) : Nil

Remove a model from the identity map

This should be called after destroying a model.

Source
reset_stats

Reset statistics

Source
set(model : Model) : Model

Store a model in the identity map

This is called automatically after loading a model from the database.

Source
size

Get the current size of the identity map

Source
stats

Get identity map statistics

Source
with

Execute a block with an identity map enabled

Within this block, loading the same record multiple times will return the same object instance.

Example

Ralph::IdentityMap.with do
  user1 = User.find(1)
  user2 = User.find(1)
  user1.object_id == user2.object_id # => true
end
Source

Nested types