This is the code base of the Ruby on Rails web framework.
Rails is a monorepo containing 10+ independent components that can work standalone or together.
Each component lives in its own directory at the root level:
- Active Record (
activerecord/) - ORM and database abstraction - Action Pack (
actionpack/) - Controllers and routing (contains Action Controller and Action Dispatch) - Action View (
actionview/) - View templates and helpers (extracted from Action Pack in Rails 3) - Active Model (
activemodel/) - Model interfaces without database dependency - Active Support (
activesupport/) - Core extensions and utilities used across all Rails components - Action Mailer (
actionmailer/), Action Mailbox (actionmailbox/) - Email sending/receiving - Active Job (
activejob/) - Background job abstraction - Action Cable (
actioncable/) - WebSocket integration - Active Storage (
activestorage/) - File uploads and cloud storage - Action Text (
actiontext/) - Rich text content - Railties (
railties/) - Rails CLI, generators, and framework glue
Key architectural principle: Rails components are loosely coupled. Changes to one of them should not break others unless there's an explicit dependency.
From within the component directory (preferred method):
cd actionview && bin/test # Run all tests
cd actionview && bin/test test/template/form_helper_test.rb
cd actionview && bin/test -i "/test_name/" # Filter by test name patternHow to run a specific test method:
cd actionview && bin/test test/template/form_helper_test.rb -i test_hidden_fieldHow to run the test at a specific line:
cd actionview && bin/test test/template/form_helper_test.rb:123Run all tests for a given component:
rake actionview:testRun tests across all components:
rake test # Run all tests
rake smoke # Quick smoke testHow to test individual database adapters in Active Record:
cd activerecord
bundle exec rake test:sqlite3 # Default
bundle exec rake test:postgresql
bundle exec rake test:mysql2
bundle exec rake test:trilogyImportant: Tests run in parallel using multiple processes. The bin/test script wraps Rails' custom test runner (tools/test.rb) which uses Rails::TestUnit::Runner.
When testing configuration options, use Object#with (from Active Support) to temporarily modify class attributes:
# Correct: Use Object#with for temporary config changes
ActionView::Base.with(remove_hidden_field_autocomplete: true) do
# Test code here
end
# Avoid: Manual set/restore patterns
old = ActionView::Base.remove_hidden_field_autocomplete
ActionView::Base.remove_hidden_field_autocomplete = true
# ... test code
ActionView::Base.remove_hidden_field_autocomplete = oldThis pattern is used throughout the test suite, especially for:
ActionView::Base.with(config_option: value)ActionController::Base.with(config_option: value)- Other framework configuration testing
Requires: require "active_support/core_ext/object/with" at the top of test files.
Configuration options follow a consistent pattern across components:
-
Define the attribute in the base class (e.g.,
ActionView::Base):cattr_accessor :remove_hidden_field_autocomplete, default: false
-
Check the flag before applying behavior:
@options.reverse_merge!(autocomplete: "off") unless ActionView::Base.remove_hidden_field_autocomplete
-
Enable by default in new Rails versions via
load_defaults:# In railties/lib/rails/application/configuration.rb case target_version.to_s when "8.1" action_view.remove_hidden_field_autocomplete = true end
When fixing bugs or adding features:
- Add an entry to the top of
<component>/CHANGELOG.md - Format: Brief description, then
*Your Name*on new line - See existing entries for style
- Use descriptive names:
test_hidden_field_omits_autocomplete_when_remove_hidden_field_autocomplete_is_true - Group related tests together in the file
- Test both default behavior AND explicit overrides
- Run RuboCop:
bundle exec rubocop(there's a project-wide.rubocop.yml) - Prefer
assert_notoverassert !(Rails/AssertNotcop) - Prefer
assert_dom_equalfor HTML comparisons in view tests - Use
# frozen_string_literal: trueat top of all files
Example: Issue #55984 required changes to:
- Helper class:
actionview/lib/action_view/helpers/tags/hidden_field.rb - Tests:
actionview/test/template/form_helper_test.rb - Reference: Similar fixes were in
tags/check_box.rb,tags/file_field.rb,form_tag_helper.rb,url_helper.rb
Pattern: When fixing a configuration flag, grep for similar patterns in other helpers:
grep -r "unless ActionView::Base.remove_hidden_field_autocomplete" actionview/lib/- Similar functionality: Look in the same
lib/*/helpers/orlib/*/tags/directory - Tests for a helper: Check
test/template/<helper_name>_test.rb - Configuration setup: Check
railties/lib/rails/application/configuration.rb - Default values: Look for
load_defaultsversion blocks
Action View helpers follow this structure:
- Tag helpers (
lib/action_view/helpers/tags/) - Individual form elements - Form helpers (
lib/action_view/helpers/form_helper.rb) - Form builders - Form tag helpers (
lib/action_view/helpers/form_tag_helper.rb) - Standalone tags
When modifying form behavior, check ALL three locations for consistency.
- Always reference issue numbers in commits:
Fix #12345: Description - Check for previous related PRs/issues when fixing bugs
- Bug report templates live in
guides/bug_report_templates/
lib/- Production codetest/- Test files (NOTspec/- Rails uses Minitest, not RSpec)bin/- Executable scripts (e.g.,bin/test)- Each framework is self-contained with its own Gemfile and dependencies
- Shared tools live in
tools/(e.g.,tools/test.rb,tools/release.rb)
- API docs use YARD/RDoc format
- Guides source in
guides/source/(Markdown) - Generate docs:
rake rdoc(from framework directory) - Configuration options documented in
guides/source/configuring.md
