Exploring Rails Internals

After an appropriate stint of rails-related imposture syndrome, I decided it was time to get a rough idea how rails works under the hood. Below is a list of knowledge gained / discoveries, in no particular order.

Knowledge Gained / Discoveries:

  1. How to Start a VM for Ruby on Rails Core Development
  2. Jumping Into the Console to Explore Changes
  3. Rails is Comprised of a Collection of Standalone Gems
  4. Learning How to Contribute to Rails is Easy
  5. Running Tests for Rails is Easy
  6. Ruby Has Great Introspection Methods

1. How to Start a VM for Ruby on Rails Core Development

After perusing Alex Kitchen's rails blog post and using instructions in this repository, it was simple to get a VM up and running using the latest release of rails.

This allows you to run tests / explore new features, patch bugs and issue pull requests (if you want to be a rails contributor), as well as alter code to see the impact.

2. Jumping Into the Console to Explore Changes

After using instructions in this repository to set up a rails development box, you can easily drop into irb (with local rails repos loaded) using the console tool that ships with rails available at rails/tools/console.

This allows you to easily experiment with any modification you make.

Want to know where a method on an object is defined? Try [OBJECT].method(:method_a).source_location or [CLASS].instance_method(:method_a).source_location in irb and find out!

If you are looking for where a ruby builtin method is defined, you'll have to check the C source code; look for the right C file (they're organized by class) and find the rb_define_method for the method.

3. Rails is Comprised of a Collection of Standalone Gems

Rails is comprised of a series of (mostly) standalone gems. Other than Action Mailer / Mailbox, Active Job, Action Cable, Active Storage, and Action Text, and Railties, the gems can be used outside of rails and replaced with different gems inside of rails.

As of 6.0, rails is comprised of the following core gems:

  • Action Pack: routing and controllers
  • Action View: view template lookup and rendering
  • Active Model: non-Active Record (DB) model interfaces
  • Active Record: connects and associates models with DB
  • Active Support: collection of utility classes and standard library extensions
  • Railties: glues frameworks together, handles rails initialization / bootstrapping process, manages rails CLI, provides generators core

And supplementary gems:

4. Learning How to Contribute to Rails is Easy

Rails encourages everyone to contribute to Ruby on Rails! It's easy to learn how to contribute to rails by reading their guide.

If you contribute, your name gets put on this sweet list of rails contributors!

5. Running Tests for Rails is Easy

After using instructions in this repository to set up a rails development box, running tests is simple.

With the dev box running, running tests is simple:

# All tests (be prepared to wait):
cd rails
bundle exec rake test

# Component tests:
cd railties
bundle exec rake test

# Directory within component tests:
cd railties
TEST_DIR=generators bundle exec rake test

# Specific file tests:
cd actionview
bundle exec ruby -w -Itest test/template/form_helper_test.rb

# Single test:
cd actionmailer
bundle exec ruby -w -Itest test/mail_layout_test.rb -n test_explicit_class_layout

For more tips and tricks (e.g. testing with a specific seed or DB), check out the rails testing documentation.

6. Ruby Has Great Introspection Methods

Not sure what class an object is, or what parent classes / modules it has?

object_a.class.name
object_a.ancestors

Not sure if an object is an instance of a certain class?

object_a.instance_of?(ClassA)

Not sure what methods an object / class has?

ClassA.methods
ClassA.instance_methods

Not sure if a method is available to a given object?

object_a.respond_to?(:method_a)

Want to see the instance variables of an object?

object_a.instance_variables

Other Takeaways

  • Checking out the *.gemspec in the root folder of a gem quickly shows you its dependencies
  • There is a great guide explaining how rails autoloading / reloading works. Check out rails/activesupport/lib/active_support/dependencies/autoload.rb to see the code
  • In the first level of rails gems (e.g. Active Record), the lib directory contains a file with the name of the module (e.g. active_record.rb), which configures how the gem is loaded when it’s started up
  • Some gems have a rails/generators directory which holds the generators pertaining to the gem (e.g. rails g model)
  • git log -S --reverse --patch --pickaxe-all; A way to search commits in reverse order with all code changes