Overview
Relevant Files
README.mdCONTRIBUTING.mdrails.gemspecrailties/README.rdoc
Rails is a full-stack web application framework optimized for programmer happiness and sustainable productivity. It encourages beautiful code by favoring convention over configuration, and is built on the Model-View-Controller (MVC) architectural pattern.
What is Rails?
Rails provides everything needed to create database-backed web applications. The framework is composed of multiple independent gems that can be used together or separately, each handling a specific aspect of web development. Rails requires Ruby 3.2.0 or higher and is released under the MIT License.
Core Architecture: The MVC Pattern
Rails divides applications into three distinct layers:
-
Model Layer - Represents domain objects (Account, Product, Post, etc.) and encapsulates business logic. Models are typically backed by databases through Active Record, though they can also be plain Ruby classes using Active Model interfaces.
-
View Layer - Responsible for rendering application resources in various formats (HTML, JSON, XML, PDFs). Views are typically ERB templates (Embedded Ruby) and are handled by Action View.
-
Controller Layer - Handles incoming HTTP requests, loads/manipulates models, and renders appropriate responses. Controllers are derived from
ActionController::Baseand are managed by Action Pack (which includes Action Dispatch for routing).
Framework Components
Rails is composed of 11 core gems that work together seamlessly:
Core MVC Components:
- Active Record: Object-relational mapping for database interactions
- Active Model: Toolkit for building modeling frameworks
- Action Pack: Web-flow and rendering (routing, controllers, views)
- Action View: Template rendering and view helpers
Supporting Frameworks:
- Active Support: Utility classes and standard library extensions
- Action Mailer: Email generation and delivery
- Action Mailbox: Incoming email handling
- Active Job: Background job processing with multiple queue backends
- Action Cable: WebSocket integration for real-time features
- Active Storage: File attachment and cloud storage management
- Action Text: Rich text content handling
Bootstrapping:
- Railties: Application initialization, CLI, and generators
Dependency Structure
Loading diagram...
Getting Started
To create a new Rails application:
gem install rails
rails new myapp
cd myapp
bin/rails server
The application will be available at http://localhost:3000.
Contributing
Rails welcomes contributions from the community. The project uses GitHub for issue tracking and pull requests. Contributors should follow the guidelines in CONTRIBUTING.md and refer to the Contributing to Ruby on Rails guide for coding conventions and best practices.
Architecture & MVC Pattern
Relevant Files
activerecord/README.rdocactionpack/README.rdocactionview/README.rdocrailties/README.rdocactivesupport/README.rdoc
Rails follows the Model-View-Controller (MVC) architectural pattern, which divides applications into three distinct layers, each with specific responsibilities. This separation of concerns enables maintainability, testability, and scalability.
The MVC Pattern
Loading diagram...
Model Layer
The Model represents your application's domain logic and data. Models encapsulate business rules and interact with the database.
- Active Record provides object-relational mapping (ORM) for database-backed models
- Models inherit from
ActiveRecord::Baseand automatically map to database tables - Active Model allows non-database models to use Rails conventions and validations
- Models define associations (
has_many,belongs_to,has_one) to represent relationships
Example:
class Product < ActiveRecord::Base
has_many :reviews
validates :name, presence: true
end
View Layer
The View is responsible for rendering the user interface. Views present data to users in various formats.
- Action View handles template lookup and rendering
- Supports ERB (Embedded Ruby) for mixing HTML with Ruby code
- Provides view helpers for building forms, links, and other HTML elements
- Can render multiple formats: HTML, JSON, XML, PDF
Example:
<h1><%= @product.name %></h1>
<p><%= @product.description %></p>
Controller Layer
The Controller handles incoming HTTP requests and orchestrates the response.
- Action Dispatch routes requests to appropriate controllers
- Action Controller provides the base class for controllers
- Controllers load models, execute business logic, and render views
- Actions are controller methods that respond to HTTP requests
Example:
class ProductsController < ApplicationController
def show
@product = Product.find(params[:id])
end
end
Supporting Frameworks
- Railties bootstraps the Rails application and manages the CLI
- Active Support provides utility classes and Ruby extensions used throughout Rails
- Action Mailer handles email generation and delivery
- Active Job manages background job processing
- Action Cable integrates WebSockets for real-time features
Active Record - Object-Relational Mapping
Relevant Files
activerecord/lib/active_record/base.rbactiverecord/lib/active_record/associations.rbactiverecord/lib/active_record/migration.rbactiverecord/lib/active_record/connection_adapters.rbactiverecord/lib/arel.rbactiverecord/lib/active_record/relation.rb
Active Record is Rails' object-relational mapping (ORM) layer that bridges Ruby objects and relational databases. It eliminates the need for manual SQL by automatically mapping classes to database tables and providing a rich query interface.
Core Architecture
Active Record follows the convention over configuration principle. When you create a model class inheriting from ApplicationRecord (which extends ActiveRecord::Base), it automatically maps to a database table with a matching name:
class User < ApplicationRecord
end
# Automatically maps to the "users" table
The Base class is a composition of multiple modules that provide different capabilities: Persistence for CRUD operations, Associations for relationships, Validations for data integrity, Callbacks for lifecycle hooks, and Querying for building SQL queries.
Associations: Defining Relationships
Associations express relationships between models using declarative macros:
class Author < ApplicationRecord
has_many :books
end
class Book < ApplicationRecord
belongs_to :author
has_and_belongs_to_many :categories
end
The four primary association types are:
belongs_to– One-to-one relationship where the model owns a foreign keyhas_one– One-to-one relationship where the model is referenced by a foreign keyhas_many– One-to-many relationship; returns a collectionhas_and_belongs_to_many– Many-to-many relationship through a join table
Associations automatically generate methods for accessing and manipulating related records, with support for eager loading, scoping, and nested attributes.
Query Interface and Arel
Active Record queries are built using a chainable, lazy-evaluated API powered by Arel (A Relational Algebra), an abstract SQL syntax tree builder:
User.where(active: true)
.joins(:posts)
.select(:id, :name)
.order(created_at: :desc)
.limit(10)
The Relation class represents a query in progress. Each method like where, select, and order returns a new Relation object, enabling method chaining. The query is only executed when you call a terminal method like first, all, or count.
Arel translates these chainable calls into SQL:
User.where(name: "Alice").to_sql
# SELECT "users".* FROM "users" WHERE "users"."name" = 'Alice'
Migrations: Schema Evolution
Migrations provide version-controlled schema changes:
class CreateUsers < ActiveRecord::Migration[8.2]
def change
create_table :users do |t|
t.string :name
t.string :email
t.timestamps
end
end
end
Migrations track applied versions in the schema_migrations table, allowing forward and backward schema evolution across environments.
Connection Adapters
Active Record abstracts database differences through adapter plugins. Built-in adapters support:
- SQLite3 – Lightweight, file-based
- MySQL2 / Trilogy – MySQL-compatible databases
- PostgreSQL – Advanced relational database
Adapters are registered and resolved dynamically, allowing custom database support without modifying core code.
ActiveRecord::Base.establish_connection(
adapter: 'postgresql',
host: 'localhost',
database: 'myapp'
)
Persistence and Lifecycle
Models support full CRUD operations with automatic timestamp management:
user = User.new(name: "Bob")
user.save # INSERT
user.update(name: "Robert") # UPDATE
user.destroy # DELETE
Callbacks hook into the lifecycle (before_save, after_create, etc.), enabling custom logic during persistence operations.
Action Pack - Routing & Controllers
Relevant Files
actionpack/lib/action_controller/base.rbactionpack/lib/abstract_controller/base.rbactionpack/lib/action_dispatch/routing.rbactionpack/lib/action_dispatch/routing/route_set.rbactionpack/lib/action_dispatch/routing/mapper.rbactionpack/lib/action_dispatch/journey/router.rb
Overview
Action Pack is Rails' HTTP request handling layer, split into two main components: routing (ActionDispatch) and controllers (ActionController). The routing system maps incoming HTTP requests to controller actions, while controllers process those requests and generate responses.
Request Flow
When a request arrives, it flows through the middleware stack and reaches the routing layer:
- RouteSet (the Rack app) receives the request via
call(env) - Journey::Router matches the request path against registered routes
- Route object is selected and its app (typically a controller dispatcher) is invoked
- Controller action is executed and returns a response
Loading diagram...
Routing System
ActionDispatch::Routing defines routes in config/routes.rb. Routes map URL patterns to controller actions using a declarative DSL:
resources :posts # RESTful routes
get '/articles/:year/:month/:day', to: 'articles#show'
namespace :admin do
resources :users
end
RouteSet maintains a collection of routes and acts as a Rack middleware. It uses Journey, an internal routing engine that compiles routes into an optimized state machine for fast matching.
Journey::Router performs pattern matching using a Generalized Transition Graph (GTG) simulator. Routes are parsed into an Abstract Syntax Tree (AST), compiled into a transition table, and matched against incoming paths. This approach is faster than iterating through routes sequentially.
Controllers
AbstractController::Base is the low-level foundation. It defines the core action dispatch mechanism:
process(action)— Finds and executes the action methodaction_methods— Cached set of public methods that are valid actionscontroller_path— Underscored controller name (e.g.,admin/posts)
ActionController::Base extends AbstractController with HTTP-specific features through mixins:
- Rendering — Template rendering and response generation
- Redirecting — HTTP redirects
- StrongParameters — Parameter filtering and validation
- RequestForgeryProtection — CSRF token handling
- Cookies & Flash — Session data management
- MimeResponds — Content negotiation (JSON, HTML, etc.)
- Caching — HTTP caching headers and fragment caching
Actions are public instance methods. The router extracts :controller and :action from the matched route and dispatches to the appropriate action.
Named Routes & URL Helpers
Routes can be named with the :as option, generating helper methods:
get '/login', to: 'sessions#new', as: 'login'
# Generates: login_path, login_url
NamedRouteCollection maintains these helpers in anonymous modules that are mixed into controllers and views, enabling convenient URL generation without hardcoding paths.
Action View - Template Rendering
Relevant Files
actionview/lib/action_view/base.rbactionview/lib/action_view/template.rbactionview/lib/action_view/renderer/renderer.rbactionview/lib/action_view/renderer/template_renderer.rbactionview/lib/action_view/lookup_context.rbactionview/lib/action_view/template/resolver.rb
Action View's template rendering system is the core mechanism that transforms template files into rendered HTML output. The process involves template discovery, compilation to Ruby methods, and execution within a view context.
Template Discovery and Lookup
The rendering pipeline begins with LookupContext, which manages template discovery. It holds view paths and template details (locale, format, variant, handler) and delegates to Resolver objects to find templates on disk. The resolver uses regex patterns to parse template filenames and extract metadata like format (.html, .json) and handler (.erb, .builder).
# LookupContext finds templates based on name, prefix, and details
lookup_context.find_template("posts/show", ["posts"], false, {})
Template Compilation Pipeline
When a template is rendered, the Template class orchestrates compilation:
- Source Loading: Template source is read from disk and validated for encoding
- Handler Processing: The appropriate handler (ERB, Builder, etc.) transforms template syntax into Ruby code
- Method Generation: The handler output is wrapped in a method definition with proper parameter handling
- Module Evaluation: The method is evaluated into a module (the
compiled_method_container)
# Simplified compilation flow
def compiled_source
source = encode! # Ensure UTF-8 encoding
code = @handler.call(self, source) # Handler transforms template
# Wrap in method definition
"def #{method_name}(local_assigns, output_buffer, &_)\n#{code}\nend"
end
Thread-Safe Compilation
Templates use a compile mutex to ensure thread-safe compilation. The first thread to request a template compiles it; subsequent threads wait and reuse the compiled method. This prevents race conditions in multi-threaded environments.
Rendering Execution
The Renderer class is the main entry point. It delegates to specialized renderers:
- TemplateRenderer: Renders full templates with optional layouts
- PartialRenderer: Renders partial templates with local variable passing
- CollectionRenderer: Renders partials for collections
- StreamingTemplateRenderer: Streams template output for large responses
# Main render entry point
renderer.render(context, options) # Returns rendered string
renderer.render_body(context, options) # Returns Rack-compatible body
Template Execution Context
Templates execute within a view context (instance of ActionView::Base or subclass). The context provides:
- Access to helpers (form helpers, tag helpers, etc.)
- Instance variables from the controller
- The
_runmethod that invokes compiled template methods - Output buffering via OutputBuffer
Strict Locals and Parameter Validation
Templates can declare strict locals using a magic comment:
<%# locals: (title:, author: nil) %>
<h1><%= title %></h1>
This generates keyword arguments in the compiled method, enabling parameter validation and IDE support. The template compilation process extracts these declarations and enforces them at render time.
Caching and Performance
- Template Caching: Compiled templates are cached in memory; source is discarded after compilation
- Resolver Caching: Template lookups are cached by LookupContext to avoid repeated filesystem access
- Digest Caching: Template digests (for cache busting) are cached per detail combination
The rendering system balances flexibility (multiple template formats, handlers, and locales) with performance through strategic caching and lazy compilation.
Railties - Framework Bootstrap & CLI
Relevant Files
railties/lib/rails/application.rbrailties/lib/rails/command.rbrailties/lib/rails/generators.rbrailties/lib/rails/engine.rbrailties/lib/rails/railtie.rbrailties/lib/rails/application/bootstrap.rb
Railties is the glue that holds the Rails framework together. It manages three critical responsibilities: the application bootstrap process, the command-line interface, and the code generators system. Understanding these components is essential for working with Rails internals.
Core Architecture
The Railties module is built on a hierarchy of extensible classes:
- Rails::Railtie - The foundation class that provides hooks for extending Rails and modifying initialization
- Rails::Engine - A Railtie with additional capabilities for wrapping Rails functionality as reusable packages
- Rails::Application - An Engine with responsibility for coordinating the entire boot process
Each major Rails component (Action Mailer, Action Controller, Active Record, etc.) implements a Railtie, making Rails itself component-agnostic and allowing custom components to replace defaults.
Bootstrap Process
When a Rails application starts, it follows a precise initialization sequence:
1. Load config/boot.rb (sets up load paths)
2. Require railties and engines
3. Define Rails.application class
4. Run before_configuration callbacks
5. Load config/environments/ENV.rb
6. Run before_initialize callbacks
7. Execute Railtie initializers (engines set up load paths, routes, config/initializers/*)
8. Build middleware stack and run to_prepare callbacks
9. Eager load if configured
10. Run after_initialize callbacks
The Rails::Application::Bootstrap module defines early-stage initializers that set up logging, error reporting, caching, and Active Support. The Finisher module runs final initialization steps after all railties have completed.
Command System
The CLI is powered by Rails::Command, which uses Thor for command parsing. Commands are discovered dynamically by looking for files ending in _command.rb in load paths.
Rails::Command.invoke :server, ["--port", "3000"]
The command lookup follows a namespace pattern: namespace:command_name. Rails searches for commands in multiple locations, allowing gems to extend the CLI without modifying core files. Common commands include generate, server, console, test, and db.
Generators Framework
Rails::Generators provides a Thor-based system for code generation. Generators are configured with:
- Aliases - Short flags like
-ofor--orm - Options - Default settings for generators (ORM, template engine, test framework)
- Fallbacks - Fallback generators when a specific one isn't available
- Templates - Custom template paths for generator output
Generators can be extended by gems through the Railtie generators block, allowing plugins to provide custom scaffolding and code generation.
Initializers and Configuration
Railties use the initializer macro to hook into the boot process:
class MyGem::Railtie < Rails::Railtie
initializer "my_gem.setup" do |app|
app.middleware.use MyGem::Middleware
end
end
Initializers can specify :before and :after options to control execution order. The config object is shared across all railties and the application, enabling coordinated configuration.
Rake Tasks and Server Hooks
Railties can contribute Rake tasks and server startup hooks:
rake_tasks do
load "path/to/tasks.rake"
end
server do
WebpackServer.start
end
This allows gems to extend Rails functionality without requiring manual setup by developers.
Active Support - Utilities & Extensions
Relevant Files
activesupport/lib/active_support/core_extactivesupport/lib/active_support/cache.rbactivesupport/lib/active_support/callbacks.rbactivesupport/lib/active_support/concern.rb
Active Support provides a comprehensive toolkit of utilities and language extensions that enhance Ruby's standard library and provide common patterns used throughout Rails. These utilities are organized into three main categories: core extensions, caching infrastructure, and lifecycle management.
Core Extensions
Core extensions add methods to Ruby's built-in classes to make common operations more convenient. They are organized by class and can be loaded selectively or all at once.
Key Extension Categories:
- Object Extensions –
blank?,present?,try,deep_dup,with_options - String Extensions –
humanize,titleize,pluralize,to_date,truncate - Array Extensions –
extract_options,grouping,wrap,extract - Hash Extensions –
with_indifferent_access,deep_merge,slice,except - Numeric Extensions – Time helpers like
5.days,2.hours,1.kilobyte - Date/Time Extensions –
beginning_of_week,end_of_month,advance,change
require "active_support/core_ext"
# String inflections
"hello_world".camelize # => "HelloWorld"
"HelloWorld".underscore # => "hello_world"
# Numeric time helpers
5.days.ago # => Time from 5 days ago
2.weeks.from_now # => Time 2 weeks in future
# Hash indifferent access
hash = { a: 1 }.with_indifferent_access
hash['a'] # => 1 (string key works)
Callbacks System
The Callbacks module enables lifecycle hooks in classes, allowing code to run at specific points in an object's lifecycle. This is fundamental to Rails models and controllers.
Three Callback Types:
- Before callbacks – Run before an event
- After callbacks – Run after an event
- Around callbacks – Wrap the event, controlling execution
class Record
include ActiveSupport::Callbacks
define_callbacks :save
def save
run_callbacks :save do
puts "Saving..."
end
end
end
class PersonRecord < Record
set_callback :save, :before, :validate
set_callback :save, :after, :notify_observers
def validate
puts "Validating..."
end
end
Concern Module
ActiveSupport::Concern simplifies module composition by automatically handling the included hook and module dependencies. It eliminates boilerplate when mixing modules into classes.
module Taggable
extend ActiveSupport::Concern
included do
has_many :tags
end
class_methods do
def find_by_tag(name)
joins(:tags).where(tags: { name: name })
end
end
def tag_list
tags.pluck(:name).join(", ")
end
end
class Article
include Taggable # Automatically includes dependencies
end
Caching Infrastructure
Active Support provides a flexible caching layer with multiple backend implementations. The Cache::Store abstract class defines the interface, with concrete implementations for different storage backends.
Available Cache Stores:
MemoryStore– In-process memory (development/testing)FileStore– Filesystem-based persistenceMemCacheStore– Memcached backendRedisCacheStore– Redis backendNullStore– No-op cache (testing)
cache = ActiveSupport::Cache.lookup_store(:memory_store)
cache.write('user_1', user_data, expires_in: 1.hour)
cache.read('user_1') # => user_data
cache.fetch('user_2') do
expensive_operation
end
cache.delete('user_1')
Module Delegation
The delegate macro simplifies forwarding method calls to contained objects, reducing boilerplate for composition patterns.
class Greeter
def hello
"Hello!"
end
end
class Person
def initialize
@greeter = Greeter.new
end
delegate :hello, to: :@greeter
end
Person.new.hello # => "Hello!"
Integration Points
These utilities work together throughout Rails:
- Models use Callbacks for lifecycle hooks and Concern for shared behavior
- Controllers use Callbacks for filters and Concern for shared logic
- Caching integrates with models via
cache_keyand fragment caching - Core Extensions provide the foundation for readable, expressive Rails code
Loading diagram...
Additional Frameworks - Jobs, WebSockets & Storage
Relevant Files
activejob/lib/active_jobactioncable/lib/action_cableactivestorage/lib/active_storageactionmailer/libactiontext/libactionmailbox/lib
Rails provides several specialized frameworks beyond the core MVC stack to handle background jobs, real-time communication, file storage, email, rich text, and inbound email processing. These frameworks integrate seamlessly with the rest of Rails while solving specific domain problems.
Active Job – Background Job Processing
Active Job is Rails' abstraction layer for background job processing. It provides a unified API for declaring and enqueueing jobs, regardless of the underlying queuing backend (Sidekiq, Resque, Delayed Job, etc.).
Key concepts:
- Jobs inherit from
ActiveJob::Baseand define aperformmethod - Jobs are enqueued with
perform_lateror scheduled withset(wait_until:)andset(wait:) - Supports GlobalID serialization for passing Active Record objects directly
- Built-in adapters for multiple queuing systems; library authors can provide custom adapters
- Includes continuations for interrupting and resuming long-running jobs
class ProcessImageJob < ActiveJob::Base
queue_as :images
def perform(image_id)
image = Image.find(image_id)
image.process_variants
end
end
ProcessImageJob.set(wait: 1.hour).perform_later(image.id)
Action Cable – Real-Time WebSockets
Action Cable integrates WebSockets into Rails, enabling real-time bidirectional communication between server and clients. It provides both server-side Ruby and client-side JavaScript frameworks.
Architecture:
- Connections handle WebSocket lifecycle and authentication
- Channels define subscription logic and message broadcasting
- Subscription adapters (Redis, PostgreSQL, inline) manage pub/sub across server instances
- Full access to domain models and Active Record within channels
class ChatChannel < ApplicationCable::Channel
def subscribed
stream_from "chat_#{params[:room_id]}"
end
def send_message(data)
ActionCable.server.broadcast(
"chat_#{params[:room_id]}",
message: data['text']
)
end
end
Active Storage – Cloud File Management
Active Storage provides a unified interface for attaching files to Active Record models and storing them in cloud services (S3, Google Cloud Storage) or local disk. Files are stored separately from the database using polymorphic associations.
Core components:
- Blob – Immutable file metadata and storage service reference
- Attachment – Polymorphic join model linking blobs to application models
- Service – Pluggable storage backends (S3, GCS, disk, mirror)
- Variants – On-demand image transformations using MiniMagick or Vips
- Direct uploads – Client-side uploads directly to cloud storage
class User < ApplicationRecord
has_one_attached :avatar
has_many_attached :documents
end
user.avatar.attach(io: File.open("face.jpg"), filename: "face.jpg")
image_tag user.avatar.variant(resize_to_limit: [100, 100])
Action Mailer – Email Delivery
Action Mailer provides a framework for composing and sending emails using templates, similar to how Action Controller renders views. It integrates with Active Job for asynchronous delivery via deliver_later.
class WelcomeMailer < ApplicationMailer
default from: 'noreply@example.com'
def welcome_email(user)
@user = user
mail(to: user.email, subject: 'Welcome!')
end
end
WelcomeMailer.welcome_email(user).deliver_later
Action Text – Rich Text Editing
Action Text brings rich text editing to Rails using the Trix editor. Rich text content is stored in a RichText model associated with any Active Record model. Embedded images and attachments are automatically managed by Active Storage.
class Post < ApplicationRecord
has_rich_text :content
end
post.content = "Rich text with <strong>formatting</strong> and images"
Action Mailbox – Inbound Email Processing
Action Mailbox routes incoming emails to controller-like mailboxes for processing. It supports multiple ingresses (Mailgun, Postmark, SendGrid, Exim, Postfix, Qmail) and stores inbound emails as InboundEmail records with lifecycle tracking and cloud storage integration.
class ForwardMailbox < ApplicationMailbox
def process
case inbound_email.mail.from
when /support@/
create_support_ticket(inbound_email)
end
end
end
Loading diagram...
These frameworks work together to provide a complete solution for modern Rails applications: Active Job handles background work, Action Cable enables real-time features, Active Storage manages files, Action Mailer sends notifications, Action Text provides rich editing, and Action Mailbox processes incoming email—all with Rails' characteristic simplicity and integration.