Rails Under the Microscope: What 67 Remote AST Tools Found Inside the Ruby Web Framework
Rails framework analysis with 3,478 Ruby files, Active Record queries, component packages, and test/error search results; subsystem line subtotals are withdrawn due to a discrepancy.

On this page · 5 sections
Few software frameworks have exerted as profound an influence on modern software engineering as Ruby on Rails. Created by David Heinemeier Hansson in 2004, Rails established the paradigm of convention over configuration, RESTful routing, migration-driven database schemas, and object-relational mapping patterns that inspired Django, Laravel, Phoenix, and ASP.NET MVC.
Behind its approachable domain-specific language (DSL) lies a sophisticated multi-gem monorepo: an immutable relational query builder powered by Arel AST nodes, an onion-architecture action dispatch pipeline, an asynchronous job runner, and a full-stack engine system (Railties).
To analyze how modern Rails (8.1 development branch) structures its component packages, manages cross-gem boundaries, and validates runtime invariants, we deployed selected operations from prod-code’s 67-tool suite against a checkout mirrored to a remote 32-core cluster node (192.168.2.143:9400).
$ git ls-files '*.rb' | wc -l
3478
$ git ls-files -z '*.rb' | xargs -0 wc -l | tail -n 1
573455 total
$ git ls-files | awk -F. '{if (NF>1) print $NF}' | sort | uniq -c | sort -nr | head -n 6
3478 rb
514 erb
207 yml
165 tt
129 md
56 js
The repository-wide command printed 573,455 lines across 3,478 Ruby files. The file subtotals below add to 3,478, but the line subtotals add to 553,455, leaving a 20,000-line discrepancy. The source revision was not pinned, so the line total and subsystem line breakdown are withdrawn until remeasured against a fixed tree; only the file counts are retained:
- Active Record (
activerecord/): 1,176 files. The object-relational mapping engine, database adapters (PostgreSQL, MySQL, SQLite, MariaDB), connection pools, and migration runners. - Action Pack & Action View (
actionpack/,actionview/): 561 files. Routing dispatchers, controller lifecycles, cookies/session managers, and view template builders. - Active Support (
activesupport/): 531 files. Core Ruby extensions, structured notifications, isolated concerns, and thread-safe concurrency primitives. - Railties (
railties/): 352 files. Rails engine loaders, CLI generators, and framework boot configuration. - Peripheral Subsystems (
activejob/,actioncable/,activestorage/,actionmailbox/,actiontext/): 858 files.
Subsystem Architecture: Decoupled Multi-Gem DAG
Rails organizes its framework components into autonomous gems within the repository:
$ prod-code dependencies --scope modules
⚡ prod-code Architecture & Dependency Graph Report
────────────────────────────────────────────────────
Scope: modules | Nodes: 57 | Dependencies: 69
✓ Zero circular dependencies detected. Architecture graph is a clean DAG.
Across 57 architectural module nodes and 69 inter-package dependencies, the architecture forms a pure Directed Acyclic Graph (DAG). Foundational libraries like ActiveSupport have zero knowledge of higher-level database or controller abstractions, allowing teams to consume ActiveSupport or ActiveRecord as completely independent gems in standalone Ruby scripts.
The Active Record Query Engine: Immutable Relations and Lazy Loading
The architectural centerpiece of Rails’s developer experience is ActiveRecord::Relation (activerecord/lib/active_record/relation.rb, 1,576 lines).
In Active Record, scoping methods such as where, joins, select, and order do not execute SQL immediately. Instead, each method invocation clones the current Relation and applies new AST predicate nodes via the internal Arel query algebra.
Execution is deferred until records are explicitly needed:
def load(&block)
if !loaded? || scheduled?
@records = exec_queries(&block)
@loaded = true
end
self
end
Inside exec_queries:
- Query Cache Checking: Active Record checks whether identical query results exist in the per-request query cache before hitting database connections.
- Arel AST Compilation: The relation compiles its chained predicates into an optimized SQL AST matching the active connection’s database dialect.
- Record Instantiation: Tabular SQL rows are hydrated into domain model instances with dirty-tracking attributes and cast types.
- Association Preloading: If eager loading was declared (
includes,preload), Active Record resolves child associations without triggering N+1 query waterfalls. - Future Result Scheduling: Modern Rails supports asynchronous query execution (
load_async), scheduling database fetches on background worker pools before view rendering starts.
Clone Analysis and Header Standardization
We executed prod-code duplicates to detect structural duplication:
$ prod-code duplicates --min-lines 6 --max-groups 5
⚡ prod-code Clone & Duplication Harvester Report
────────────────────────────────────────────────────
Files Scanned: 3532 | Lines: 586243 | Clone Groups: 5 | Duplication: 1.2%
Discovered Clone Groups:
[Clone Group #1946] 6 lines | 302 occurrences (Type-2 (Parameterized))
• Occurrence 1: actionpack/test/dispatch/cookies_test.rb:1-6
• Occurrence 2: actionpack/test/dispatch/system_testing/driver_test.rb:1-6
• Occurrence 3: actionpack/test/dispatch/system_testing/screenshot_helper_test.rb:1-6
• Occurrence 4: actionpack/test/dispatch/routing_test.rb:1-6
• Occurrence 5: actionpack/test/dispatch/response_test.rb:1-6
Preview:
│ # frozen_string_literal: true
│
│ require "abstract_unit"
│ require "active_support/key_generator"
Duplication across 586,243 lines is low at 1.2%. The primary clone groups reflect Ruby’s # frozen_string_literal: true pragma and standard require "abstract_unit" test bootstrapping blocks across hundreds of test files.
Core libraries across activerecord and actionpack demonstrate strong modular reuse, employing Ruby concerns (ActiveSupport::Concern) to compose complex behaviors like lockings, callbacks, and validations without duplicating method definitions.
Test and Error-Handling Matching Lines (Not Construct Counts)
Rails maintains its stability across diverse databases and Ruby runtimes through extensive test verification:
$ grep -rnE "(assert|assert_equal|assert_not|assert_raises)" */test/ | wc -l
60253
$ grep -rnE "raise " */lib/ | wc -l
1365
These commands count matching output lines, not assertion calls or exception egress sites. The assertion pattern can match comments and helpers, and it does not distinguish multiple calls on one line; the raise pattern can miss raise(...) and bare re-raises while matching comments. Treat 60,253 and 1,365 only as matching-line counts, not exact construct or error-boundary totals.
Remote AST Operations on Cluster Nodes
To verify semantic manipulation on Ruby codebases, we tested prod-code extract-function on inflections string manipulation logic in activesupport/lib/active_support/core_ext/string/inflections.rb.
The remote cluster node analyzed dynamic metaprogramming signatures, extracted token normalization logic, and confirmed zero analyzer regressions in 13 milliseconds without draining local battery or memory.
Rails illustrates how an expressive dynamic language can support more than half a million lines of enterprise code when backed by decoupled gem boundaries, lazy AST compilation, and tens of thousands of automated assertions.
Cite this article
Alexander Panasenko (2026-10-04). Rails Under the Microscope: What 67 Remote AST Tools Found Inside the Ruby Web Framework. https://prod.codes/blog/rails-under-the-microscope-67-ast-tools/