Open-Source Wikis

/

Ruby on Rails

/

Packages

/

Active Record

rails/rails

Active Record

Active contributors: rafaelfranca, byroot, kamipo, eileencodes

Purpose

Active Record is Rails' ORM. It maps database rows to Ruby objects, provides a lazy chainable query DSL, and ships connection adapters for SQLite, PostgreSQL, MySQL (via mysql2 and trilogy). It is the largest component in the framework — about 70K lines of lib/ Ruby, roughly a third of the framework.

Source: activerecord/lib/active_record/ plus the Arel SQL AST library at activerecord/lib/arel/.

Directory layout

activerecord/
├── lib/
│   ├── active_record/
│   │   ├── base.rb                         # ActiveRecord::Base — the root class
│   │   ├── core.rb
│   │   ├── attributes.rb / attribute_methods/
│   │   ├── associations/                   # has_many, belongs_to, has_one, through
│   │   ├── connection_adapters/            # SQLite, PostgreSQL, MySQL2, Trilogy
│   │   ├── connection_handling.rb
│   │   ├── database_configurations/        # config/database.yml parsing
│   │   ├── encryption/                     # Encrypted attributes
│   │   ├── enum.rb
│   │   ├── fixtures.rb                     # Test fixtures
│   │   ├── future_result.rb                # Async query support
│   │   ├── locking/                        # Optimistic and pessimistic locking
│   │   ├── middleware/                     # AR-specific Rack middleware
│   │   ├── migration/                      # Schema migration DSL and runner
│   │   ├── persistence.rb / counter_cache.rb
│   │   ├── query_cache.rb / query_logs.rb
│   │   ├── relation/                       # The query builder
│   │   ├── relation.rb
│   │   ├── scoping/                        # default_scope, current_scope
│   │   ├── store.rb
│   │   ├── tasks/                          # rake db:migrate, db:create, etc.
│   │   ├── testing/                        # Parallel testing helpers
│   │   ├── transactions.rb
│   │   ├── translation.rb
│   │   ├── type/                           # Type coercion (extends ActiveModel::Type)
│   │   ├── validations.rb
│   │   ├── version.rb / gem_version.rb
│   │   └── …                               # ~80 more top-level files
│   └── arel/                               # SQL AST library
├── test/
│   ├── cases/                              # Most of the suite
│   ├── fixtures/
│   ├── models/
│   └── schema/                             # Test schema definitions
├── examples/
└── activerecord.gemspec

Key abstractions

Constant File Purpose
ActiveRecord::Base activerecord/lib/active_record/base.rb Root class for all models
ActiveRecord::Relation activerecord/lib/active_record/relation.rb Lazy, chainable query builder
ActiveRecord::ConnectionAdapters::AbstractAdapter activerecord/lib/active_record/connection_adapters/abstract_adapter.rb Base class for all adapters
ActiveRecord::ConnectionAdapters::*Adapter activerecord/lib/active_record/connection_adapters/{sqlite3,postgresql,mysql2,trilogy}_adapter.rb Concrete adapters
ActiveRecord::SchemaCache activerecord/lib/active_record/connection_adapters/schema_cache.rb Cached column / index metadata
ActiveRecord::Migration activerecord/lib/active_record/migration.rb DSL for schema changes
ActiveRecord::QueryMethods activerecord/lib/active_record/relation/query_methods.rb where, order, joins, etc.
ActiveRecord::Associations::* activerecord/lib/active_record/associations/ belongs_to / has_many / has_one
ActiveRecord::Encryption activerecord/lib/active_record/encryption/ Encrypted attributes
ActiveRecord::FutureResult activerecord/lib/active_record/future_result.rb Async query result
ActiveRecord::Type::Value activerecord/lib/active_record/type/ Per-column type coercion (extends ActiveModel::Type)
Arel::Nodes::* activerecord/lib/arel/nodes/ SQL expression tree

How a query works

graph LR
    A["User.where(name: 'Bob').limit(10)"] --> B[ActiveRecord::Relation]
    B --> C[QueryMethods append where + limit]
    C --> D[PredicateBuilder builds Arel nodes]
    D --> E[Arel AST]
    E --> F[ConnectionAdapter#to_sql]
    F --> G[Database]
    G --> H[Raw rows]
    H --> I[Type::Value.deserialize per column]
    I --> J[Model instances]

Relation records where_clause, order_clause, limit, etc. as separate nodes (relation/where_clause.rb, relation/from_clause.rb). When the relation is iterated, connection.exec_query runs the SQL and the results are typed and constructed into model instances.

The ActiveRecord::Relation#async_* methods (async_count, async_load) return FutureResult objects that materialize on first access. The async pool lives in connection_adapters/async_query_executor integration with each adapter.

Connection adapters

activerecord/lib/active_record/connection_adapters/:

abstract/                       # Shared building blocks
abstract_adapter.rb             # Base class for all adapters
abstract_mysql_adapter.rb       # Shared between mysql2 and trilogy
mysql/                          # Type definitions, schema, statement
mysql2/                         # mysql2-specific gem integration
mysql2_adapter.rb
trilogy/
trilogy_adapter.rb
postgresql/                     # PG types (jsonb, hstore, array, range, ...)
postgresql_adapter.rb
sqlite3/
sqlite3_adapter.rb
column.rb, schema_cache.rb
pool_config.rb, pool_manager.rb
statement_pool.rb

The base class AbstractAdapter defines the contract. Each concrete adapter overrides:

  • connect, disconnect, reconnect
  • Schema introspection (columns, tables, indexes, foreign_keys)
  • Schema mutation (create_table, add_column, etc.)
  • Query execution (exec_query, exec_insert, exec_update, exec_delete)
  • Transaction handling
  • Type registration

Adding a new adapter means subclassing AbstractAdapter (or AbstractMysqlAdapter for a MySQL-compatible driver) and implementing the required methods. Tests live in activerecord/test/cases/adapters/<adapter>/.

Associations

Each association kind has its own builder under activerecord/lib/active_record/associations/:

  • belongs_to_association.rb (and belongs_to_polymorphic_association.rb)
  • has_one_association.rb / has_one_through_association.rb
  • has_many_association.rb / has_many_through_association.rb
  • singular_association.rb (shared between has_one and belongs_to)
  • collection_association.rb and collection_proxy.rb

The builder/ subdirectory contains macro implementations for belongs_to, has_many, etc. The preloader/ subdirectory implements N+1 prevention via eager loading.

Multiple databases

Configured via database.yml:

production:
  primary:
    database: app_production
  primary_replica:
    database: app_production
    replica: true

Code in activerecord/lib/active_record/database_configurations/ parses the YAML, including the connections_for method that handles environments and inheritance. connection_handling.rb adds connects_to, connected_to, and while_preventing_writes. Sharding is supported via the shards: key on connects_to.

Encryption

activerecord/lib/active_record/encryption/ adds at-rest column encryption with deterministic and non-deterministic modes:

  • encrypted_attribute_type.rb — wraps any other type and encrypts on serialization.
  • cipher.rb — AES-GCM encryption.
  • key_provider.rb — pluggable key sources.
  • derived_secret_key_provider.rb — derives keys from Rails.application.credentials.
  • scheme.rb — encryption configuration per-attribute.

Public API: encrypts :ssn on a model. Documented in guides/source/active_record_encryption.md.

Migration

activerecord/lib/active_record/migration.rb plus the migration/ directory:

  • migration.rb — the change / up / down DSL.
  • migration/compatibility.rb — schema versioning so old migrations behave as expected on newer Rails.
  • migration/command_recorder.rb — records reversible migrations.
  • migration/default_strategy.rb, migration/execution_strategy.rb — strategy pattern around how DDL runs.

The runner is invoked by bin/rails db:migrate, implemented in activerecord/lib/active_record/tasks/database_tasks.rb.

Transactions and locking

  • activerecord/lib/active_record/transactions.rb — wraps Base.transaction and instance save/destroy in DB transactions.
  • activerecord/lib/active_record/connection_adapters/abstract/transaction.rb — savepoint stack and lifecycle.
  • activerecord/lib/active_record/locking/optimistic.rblock_version column.
  • activerecord/lib/active_record/locking/pessimistic.rbSELECT ... FOR UPDATE.

Integration points

  • Railtie: activerecord/lib/active_record/railtie.rb boots the connection pool, registers cache, and wires up middleware.
  • Active Model: Active Record includes ActiveModel::Validations, Callbacks, Dirty, Naming, Translation.
  • Active Job: ActiveRecord::DestroyAssociationAsyncJob runs dependent: :destroy_async.
  • Active Storage / Action Text: both use belongs_to :record, polymorphic: true against host records.
  • Action Pack: controller params are converted to AR attributes via ActiveModel::ForbiddenAttributesProtection (strong parameters integration).

Notable middleware

activerecord/lib/active_record/middleware/:

  • database_selector.rb — routes reads to a replica based on a resolver.
  • shard_selector.rb — routes requests to a shard.
  • query_logs.rb — tag SQL queries with controller / action / job comments.

Testing matrix

Run the suite against a specific adapter:

cd activerecord
bundle exec rake test:sqlite3
bundle exec rake test:postgresql
bundle exec rake test:mysql2
bundle exec rake test:trilogy

Connection details come from activerecord/test/config.yml. The CI matrix runs all four.

Entry points for modification

  • Adding a query method: add to relation/query_methods.rb and update relation.rb's Relation whitelist.
  • Adding a database type: subclass ActiveRecord::Type::Value, register on the adapter (activerecord/lib/active_record/connection_adapters/<adapter>/type.rb).
  • Adding a connection adapter: subclass AbstractAdapter (or AbstractMysqlAdapter); implement connect, schema introspection, exec_query, types. Add a test config and a test:my_adapter rake task.
  • Adding a migration helper: add to connection_adapters/abstract/schema_statements.rb or its database-specific subclasses, plus tests in activerecord/test/cases/migration/.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Active Record – Ruby on Rails wiki | Factory