Ruby & Rails Glossary

Ruby and Rails are amazing, but sometimes the terminology can be confusing. This glossary explains common Ruby & Rails concepts in plain language, with examples to help you understand.

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

Know a Ruby or Rails term that should be in our glossary? We'd love to hear from you!

Propose a New Term

Your contributions help make this resource better for everyone.

A

ActiveRecord

ActiveRecord is the ORM (Object-Relational Mapping) layer in Rails that connects your Ruby objects to database tables. It allows you to interact with your database using Ruby code instead of SQL.

# Instead of writing SQL like:
# SELECT * FROM users WHERE email = 'example@example.com' LIMIT 1;

# You can write Ruby code:
user = User.find_by(email: 'example@example.com')

🧠 Think of it like...

A translator who speaks both "Ruby" and "Database." You speak to the translator in Ruby, and they handle all the communication with the database in its native language (SQL).

Array

An Array is an ordered collection of objects in Ruby. Each object in an array is given an index number starting at 0. Arrays can contain objects of different types, including other arrays.

# Creating an array
fruits = ['apple', 'banana', 'orange']

# Accessing elements
fruits[0] # => 'apple'

# Adding elements
fruits << 'grape' # => ['apple', 'banana', 'orange', 'grape']

🧠 Think of it like...

A numbered list or a row of labeled boxes. Each box has a number (starting from 0), and you can put anything you want in each box.

Asset Pipeline

The Asset Pipeline is a framework in Rails that concatenates, minifies, and compresses JavaScript and CSS assets. It also adds asset fingerprinting for cache busting. The Asset Pipeline makes your application's assets production-ready, reducing load times and improving performance.

# In config/application.rb
config.assets.enabled = true
config.assets.version = '1.0'

# In app/assets/javascripts/application.js
//= require jquery
//= require_tree .

# In app/assets/stylesheets/application.css
/*
 *= require_self
 *= require_tree .
 */

🧠 Think of it like...

A factory assembly line for your assets. Raw materials (your CSS, JavaScript, and images) go in one end, and polished, optimized, production-ready assets come out the other end, ready to be efficiently delivered to users.

Automatic Connection Switching

Automatic Connection Switching is a feature in Rails that automatically routes database operations to the appropriate database connection based on the operation type. Read operations are sent to replica databases, while write operations are sent to the primary database, without requiring explicit connection management in your code.

# In config/database.yml
production:
  primary:
    database: my_primary_database
    adapter: mysql2
  primary_replica:
    database: my_primary_database_replica
    adapter: mysql2
    replica: true

# In app/models/application_record.rb
class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true

  connects_to database: { writing: :primary, reading: :primary_replica }
end

# Rails automatically uses the appropriate connection
# Write operation - uses primary
Post.create!(title: "New Post")

# Read operation - uses replica
@posts = Post.all

🧠 Think of it like...

A smart traffic system that automatically directs vehicles to different routes based on their type. Just as trucks might be directed to industrial roads while cars are sent through residential areas, Rails directs write operations to primary databases and read operations to replicas without the developer having to manually specify the route for each operation.

B

Block

A Block is a chunk of code that you can pass to a method. It's like an anonymous function or closure in other languages. In Ruby, blocks are enclosed in either do...end or curly braces { }.

# Block with do...end
[1, 2, 3].each do |number|
  puts number * 2
end

# Block with curly braces
[1, 2, 3].map { |number| number * 2 } # => [2, 4, 6]

🧠 Think of it like...

A recipe card that you hand to a chef (the method). The chef follows your recipe with the ingredients they have, and returns the result to you.

C

CSRF Protection

Cross-Site Request Forgery (CSRF) protection is a security mechanism that prevents attackers from tricking users into submitting unwanted requests. Rails includes built-in CSRF protection by generating unique tokens for each user session and validating these tokens on form submissions.

# In your ApplicationController:
protect_from_forgery with: :exception

# In your forms (automatically included with form_with):
<%= form_with(model: @user) do |form| %>
  <!-- CSRF token is automatically included -->
<% end %>

# For JavaScript requests, include the token in headers:
$.ajax({
  url: '/users',
  method: 'POST',
  headers: {
    'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
  }
});

🧠 Think of it like...

It's like a secret handshake between your browser and the server. When you submit a form, your browser includes the secret handshake that only it and the server know. If a request comes in without the correct handshake, the server knows it's not legitimate.

Cache Digests

Cache Digests (also known as Russian Doll Caching) is a technique in Rails that automatically adds a digest (a hash) to fragment cache keys based on the template and its dependencies. This ensures that when a nested template changes, all caches that include it are automatically invalidated.

# In a view template
<% cache @product do %>
  <%= render @product %>
  <% cache @product.reviews do %>
    <%= render @product.reviews %>
  <% end %>
<% end %>

# The cache key includes a digest of the template and its dependencies
# So if the 'reviews' partial changes, the outer cache is also invalidated

🧠 Think of it like...

A set of Russian nesting dolls. Each doll (cached fragment) contains smaller dolls (nested cached fragments). If you change one of the inner dolls, you need to replace all the outer dolls that contain it too. Cache digests automatically handle this for you.

Class

A Class is a blueprint for creating objects. It defines what attributes and methods the objects will have. In Ruby, everything is an object, and every object is an instance of a class.

# Defining a class
class Dog
  def initialize(name, breed)
    @name = name
    @breed = breed
  end

  def bark
    "Woof! I'm #{@name} the #{@breed}."
  end
end

# Creating an instance
fido = Dog.new("Fido", "Labrador")
fido.bark # => "Woof! I'm Fido the Labrador."

🧠 Think of it like...

A cookie cutter. The class is the cookie cutter, and the objects are the cookies. Each cookie has the same shape (methods) but can have different decorations (attribute values).

Closure

A Closure is a function or reference to a function together with a referencing environment. In Ruby, closures are implemented as blocks, procs, and lambdas. They "close over" variables from their surrounding scope.

def counter
  count = 0
  return -> { count += 1 }
end

increment = counter
increment.call # => 1
increment.call # => 2
increment.call # => 3

🧠 Think of it like...

A backpack that a function carries around. The backpack contains all the variables that were in scope when the function was defined, and the function can access them even when it's called elsewhere.

Cross-Site Scripting (XSS)

Cross-Site Scripting (XSS) is a security vulnerability that allows attackers to inject client-side scripts into web pages viewed by other users. In Rails, this can happen when user input is rendered in views without proper escaping.

# Vulnerable to XSS:
<%= raw user_input %> # NEVER DO THIS!
<%= user_input.html_safe %> # ALSO DANGEROUS!

# Safe from XSS (automatic escaping):
<%= user_input %>

# For trusted HTML content, use sanitize:
<%= sanitize user_input %>

🧠 Think of it like...

It's like a graffiti artist being allowed to write anything on a wall that everyone in town has to look at. Instead of just writing a message, they could write instructions that trick people into giving away their personal information.

D

DSL (Domain Specific Language)

A Domain Specific Language is a mini-language designed for a specific task or domain. Ruby's flexible syntax makes it great for creating DSLs. Rails, RSpec, and Rake all use DSLs to make their code more readable and expressive.

# RSpec is a DSL for testing
describe User do
  it "validates email presence" do
    user = User.new(email: nil)
    expect(user).not_to be_valid
  end
end

# ActiveRecord migrations use a DSL
create_table :users do |t|
  t.string :name
  t.string :email
  t.timestamps
end

🧠 Think of it like...

A specialized dialect of a language. Just as doctors have medical terminology that helps them communicate precisely about medical issues, a DSL gives programmers specialized vocabulary and grammar for a specific domain.

Database Switching

Database Switching is a feature in Rails that allows you to manually switch between different database connections. This is useful when you need to perform operations on a specific database in a multiple database setup.

# Switch to the reading role
ActiveRecord::Base.connected_to(role: :reading) do
  # All code in this block uses the reading database
  @posts = Post.all
end

# Switch to the writing role
ActiveRecord::Base.connected_to(role: :writing) do
  # All code in this block uses the writing database
  Post.create!(title: "New Post")
end

# Switch to a specific database
ActiveRecord::Base.connected_to(database: :animals_primary) do
  Dog.create!(name: "Fido")
end

🧠 Think of it like...

A railroad switch operator. Just as a switch operator can direct a train to different tracks, database switching allows you to direct your database operations to different databases based on your needs.

Duck Typing

Duck Typing is a programming concept where the type or class of an object is less important than the methods it defines. "If it walks like a duck and quacks like a duck, then it's a duck." In Ruby, you don't need to declare types, and any object can be used in any context as long as it supports the methods being called.

# These classes have nothing in common except the 'speak' method
class Dog
  def speak
    "Woof!"
  end
end

class Cat
  def speak
    "Meow!"
  end
end

# This method doesn't care about the class, only that 'speak' exists
def make_noise(animal)
  animal.speak
end

make_noise(Dog.new) # => "Woof!"
make_noise(Cat.new) # => "Meow!"

🧠 Think of it like...

A universal remote control. It doesn't matter if you're controlling a TV, DVD player, or sound system - as long as the device responds to "power," "volume up," and "volume down" buttons, the remote will work with it.

E

Enumerable

Enumerable is a module in Ruby that provides a set of methods for traversing, searching, and sorting collections. Classes that include Enumerable (like Array and Hash) gain access to methods like map, select, reject, and reduce.

numbers = [1, 2, 3, 4, 5]

# Map transforms each element
numbers.map { |n| n * 2 } # => [2, 4, 6, 8, 10]

# Select filters elements
numbers.select { |n| n.even? } # => [2, 4]

# Reduce combines elements
numbers.reduce(0) { |sum, n| sum + n } # => 15

🧠 Think of it like...

A Swiss Army knife for collections. It provides a wide range of tools for working with collections, from simple iteration to complex transformations and searches.

Exception

An Exception is an error that disrupts the normal flow of a program. In Ruby, exceptions are objects that contain information about the error. You can handle exceptions using begin/rescue blocks to prevent your program from crashing.

# Raising an exception
raise ArgumentError, "Invalid argument"

# Handling exceptions
begin
  # Code that might raise an exception
  1 / 0
rescue ZeroDivisionError => e
  puts "Error: #{e.message}"
ensure
  # This code always runs
  puts "Cleanup code"
end

🧠 Think of it like...

A fire alarm. When something goes wrong (a fire), the alarm goes off (an exception is raised). You can have a plan for what to do when the alarm sounds (rescue block), and you always want to make sure everyone is safe regardless of whether there was a fire or not (ensure block).

F

Fingerprinting

Fingerprinting in the Rails Asset Pipeline is a technique that adds a unique identifier (a hash) to asset filenames. This allows browsers to cache assets for longer periods while ensuring that when you update an asset, the browser will download the new version because the filename changes.

# In config/environments/production.rb
config.assets.digest = true

# In your view, this:
<%= image_tag "logo.png" %>

# Generates HTML like this:
<img src="/assets/logo-908e25f4bf641868d8683022a5b62f54.png" />

🧠 Think of it like...

A version stamp on a document. Just as adding "v2" to a document name tells people it's a new version, fingerprinting adds a unique code to asset filenames so browsers know when they've changed and need to be downloaded again.

Fragment Caching

Fragment Caching is a Rails technique that allows you to cache specific portions (fragments) of a view, rather than the entire page. This is useful when different parts of a page have different caching requirements or when some parts are more expensive to render than others.

# In a view template
<% cache @product do %>
  <div class="product">
    <h2><%= @product.name %></h2>
    <p><%= @product.description %></p>

    <% cache "product_pricing_#{@product.id}_#{@product.updated_at.to_i}" do %>
      <!-- Expensive pricing calculations -->
      <div class="pricing">$<%= @product.calculate_price %></div>
    <% end %>
  </div>
<% end %>

🧠 Think of it like...

A newspaper with different sections. Instead of reprinting the entire newspaper when only the sports scores change, you can just update the sports section while keeping the rest of the paper the same. Fragment caching lets you update only the parts of a page that have changed.

Freeze

Freeze is a method in Ruby that prevents an object from being modified. Once an object is frozen, attempting to modify it will raise a RuntimeError. This is useful for creating immutable objects.

string = "Hello"
string.freeze

# This will raise a RuntimeError
# string << " World"

# Creating a frozen string literal
# frozen_string_literal: true
CONSTANT = "I am immutable"

🧠 Think of it like...

Putting something in a glass display case. You can look at it, but you can't touch or modify it.

G

Garbage Collection

Garbage Collection (GC) is an automatic memory management feature in Ruby. It identifies and reclaims memory that was allocated by the program but is no longer referenced, preventing memory leaks.

# Ruby handles memory management automatically
def create_objects
  1000.times { Object.new }
end

create_objects
# After this method returns, the objects are no longer referenced
# and will be garbage collected

# You can force garbage collection
GC.start

🧠 Think of it like...

A janitor who cleans up after you. As you create objects (make a mess), the garbage collector periodically comes through and cleans up objects you're no longer using (trash), freeing up space for new objects.

Gem

A Gem is a packaged Ruby library or application. Gems are Ruby's way of distributing reusable code. They can add functionality to your Ruby programs or provide command-line utilities.

# Installing a gem
gem install rails

# Using a gem in your code
require 'rails'

# Listing installed gems
gem list

# Using Bundler to manage gems
# In Gemfile:
gem 'rails', '~> 7.0.0'
gem 'pg', '~> 1.1'

🧠 Think of it like...

A LEGO set. Each gem is a pre-built component that you can add to your project. Some gems are simple (like a single LEGO brick), while others are complex (like a LEGO castle set with many pieces).

H

Hash

A Hash is a dictionary-like collection of unique keys and their values. In Ruby, hashes are similar to arrays, but instead of using integers as indexes, you can use any object as a key.

# Creating a hash
person = { name: 'John', age: 30, city: 'New York' }

# Accessing values
person[:name] # => 'John'

# Adding or updating values
person[:email] = 'john@example.com'
person[:age] = 31

# Iterating over a hash
person.each do |key, value|
  puts "#{key}: #{value}"
end

🧠 Think of it like...

A dictionary or a phone book. You look up a word (key) to find its definition (value). In a hash, you can use any object as the "word" to look up, not just strings.

Horizontal Sharding

Horizontal Sharding is a database architecture technique that distributes data across multiple databases or database servers. In Rails, this allows you to split a single logical dataset across multiple physical databases based on a shard key, such as customer ID or geographic region.

# In config/database.yml
production:
  primary:
    database: my_primary_db
    adapter: mysql2
  primary_shard_one:
    database: my_primary_shard_one
    adapter: mysql2
  primary_shard_two:
    database: my_primary_shard_two
    adapter: mysql2

# In app/models/application_record.rb
class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true

  connects_to shards: {
    default: { writing: :primary, reading: :primary },
    shard_one: { writing: :primary_shard_one, reading: :primary_shard_one },
    shard_two: { writing: :primary_shard_two, reading: :primary_shard_two }
  }
end

# Using a specific shard
Customer.connected_to(shard: :shard_one) do
  Customer.create!(name: "Customer in shard one")
end

🧠 Think of it like...

A postal system with multiple sorting facilities. Instead of sending all mail to a single central facility (which could get overwhelmed), mail is distributed to different facilities based on zip code. Similarly, horizontal sharding distributes data across multiple databases based on a shard key, preventing any single database from becoming a bottleneck.

I

Inheritance

Inheritance is a way to create a new class that is a modified version of an existing class. The new class (subclass) inherits attributes and methods from the existing class (superclass) and can add or override them.

# Superclass
class Animal
  def speak
    "Some generic animal sound"
  end
end

# Subclass
class Dog < Animal
  def speak
    "Woof!"
  end
end

animal = Animal.new
animal.speak # => "Some generic animal sound"

dog = Dog.new
dog.speak # => "Woof!"

🧠 Think of it like...

A family tree. Children inherit traits from their parents but can also develop their own unique characteristics. Similarly, a subclass inherits from its parent class but can add or modify behavior.

Instance Variable

An Instance Variable is a variable that belongs to a specific instance of a class. In Ruby, instance variables are prefixed with an @ symbol and are accessible throughout the instance methods of the object.

class Person
  def initialize(name)
    @name = name # Instance variable
  end

  def greet
    "Hello, my name is #{@name}"
  end
end

person = Person.new("Alice")
person.greet # => "Hello, my name is Alice"

🧠 Think of it like...

A personal belonging. Just as each person has their own set of belongings (phone, wallet, keys), each instance of a class has its own set of instance variables that are separate from other instances.

L

Low-Level Caching

Low-Level Caching in Rails refers to using the Rails.cache API directly to store and retrieve arbitrary data. This gives you fine-grained control over what gets cached, for how long, and under what conditions. It's useful for caching expensive computations, API responses, or any data that's costly to generate but doesn't change frequently.

# Basic usage
Rails.cache.fetch("weather-data") do
  # Expensive API call or computation
  WeatherService.fetch_forecast
end

# With expiration
Rails.cache.fetch("weather-data", expires_in: 30.minutes) do
  WeatherService.fetch_forecast
end

# With version/cache key
Rails.cache.fetch(["user", user.id, "posts", Post.maximum(:updated_at)]) do
  user.posts.to_a
end

# Explicit cache operations
Rails.cache.write("key", value, expires_in: 1.hour)
value = Rails.cache.read("key")
Rails.cache.delete("key")

🧠 Think of it like...

A personal notebook where you jot down important information you don't want to recalculate or look up again. Just as you might write down a complex math formula to avoid recalculating it, Rails.cache lets you store any data to avoid regenerating it on every request.

M

Manifest Files

Manifest Files in the Rails Asset Pipeline are special files that tell Sprockets which assets to include and in what order. They use directives (special comments) to specify dependencies and inclusion rules for JavaScript, CSS, and other assets.

// app/assets/javascripts/application.js
//= require jquery
//= require jquery_ujs
//= require_tree .

/* app/assets/stylesheets/application.css */
/*
 *= require reset
 *= require_self
 *= require_tree .
 */

🧠 Think of it like...

A packing list for a shipment. Just as a packing list tells warehouse workers which items to include in a shipment and in what order to pack them, a manifest file tells Rails which assets to include in your application and in what order to load them.

Metaprogramming

Metaprogramming is writing code that writes or manipulates code at runtime. In Ruby, metaprogramming allows you to define methods, classes, and behavior dynamically, which can make your code more flexible and DRY (Don't Repeat Yourself).

# Defining methods dynamically
class Person
  [:name, :age, :email].each do |attribute|
    define_method("#{attribute}=") do |value|
      instance_variable_set("@#{attribute}", value)
    end

    define_method(attribute) do
      instance_variable_get("@#{attribute}")
    end
  end
end

person = Person.new
person.name = "Alice" # Calls the dynamically defined method
person.name # => "Alice"

🧠 Think of it like...

A self-modifying robot. Instead of being programmed once and running the same way forever, the robot can reprogram itself as it runs, adding new features or changing how it works based on what it encounters.

Mixin

A Mixin is a module that's included in a class to add functionality. It's a way to achieve multiple inheritance in Ruby, which only supports single inheritance. Mixins allow you to share code between unrelated classes.

# Two mixins
module Swimmable
  def swim
    "I'm swimming!"
  end
end

module Flyable
  def fly
    "I'm flying!"
  end
end

# Using mixins in classes
class Duck
  include Swimmable
  include Flyable
end

class Penguin
  include Swimmable
end

duck = Duck.new
duck.swim # => "I'm swimming!"
duck.fly # => "I'm flying!"

penguin = Penguin.new
penguin.swim # => "I'm swimming!"
# penguin.fly would raise NoMethodError

🧠 Think of it like...

Skill badges. Just as a scout might earn badges for different skills (swimming, first aid, camping), a class can include different modules to gain different sets of functionality.

Module

A Module is a collection of methods, constants, and classes that can be mixed into other classes using include, extend, or prepend. Modules provide a way to share code between classes without using inheritance.

# Defining a module
module Loggable
  def log(message)
    puts "[LOG] #{message}"
  end
end

# Including a module in a class
class User
  include Loggable

  def save
    log("User saved")
  end
end

user = User.new
user.save # => [LOG] User saved

🧠 Think of it like...

A plugin or an add-on. Just as you might add a plugin to your browser to give it new capabilities, you can include a module in your class to give it new methods and behavior.

Multiple Database Connections

Multiple Database Connections is a feature in Rails that allows an application to connect to and interact with multiple databases simultaneously. This is useful for scaling applications, separating read and write operations, or working with legacy systems.

# In config/database.yml
production:
  primary:
    database: my_primary_database
    username: root
    password: <%= ENV['DATABASE_PASSWORD'] %>
    adapter: mysql2
  primary_replica:
    database: my_primary_database_replica
    username: root_readonly
    password: <%= ENV['DATABASE_READONLY_PASSWORD'] %>
    adapter: mysql2
    replica: true
  animals:
    database: my_animals_database
    username: animals_root
    password: <%= ENV['ANIMALS_DATABASE_PASSWORD'] %>
    adapter: mysql2
    migrations_paths: db/animals_migrate

# In app/models/application_record.rb
class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true

  connects_to database: { writing: :primary, reading: :primary_replica }
end

# In app/models/animal_record.rb
class AnimalRecord < ApplicationRecord
  self.abstract_class = true

  connects_to database: { writing: :animals, reading: :animals }
end

🧠 Think of it like...

A universal remote control that can operate multiple devices. Just as the remote lets you switch between controlling your TV, sound system, and streaming box, Rails' multiple database connections let you switch between different databases for different operations or models.

O

Object

An Object is an instance of a class. In Ruby, almost everything is an object - integers, strings, arrays, even classes and modules themselves. Objects have methods and can hold state in instance variables.

# Everything is an object
42.class # => Integer
"hello".class # => String
[1, 2, 3].class # => Array

# Objects respond to methods
42.even? # => true
"hello".upcase # => "HELLO"
[1, 2, 3].length # => 3

🧠 Think of it like...

A physical object in the real world. Just as a car has properties (color, make, model) and behaviors (start, stop, turn), a Ruby object has attributes (instance variables) and behaviors (methods).

P

Page Caching

Page Caching is a technique in Rails that saves the entire HTML output of a controller action to a file on the server's file system. When a subsequent request comes in for the same page, the web server (like Nginx or Apache) can serve the static file directly without invoking the Rails application, resulting in extremely fast response times.

# In your controller
class ProductsController < ApplicationController
  caches_page :index, :show

  def index
    @products = Product.all
  end

  def show
    @product = Product.find(params[:id])
  end

  # When content changes, you need to expire the cache
  def update
    @product = Product.find(params[:id])
    if @product.update(product_params)
      expire_page action: 'show', id: @product.id
      redirect_to @product
    else
      render 'edit'
    end
  end
end

🧠 Think of it like...

A photocopier for web pages. Instead of having to recreate the same document from scratch every time someone requests it, you make a photocopy once and hand out the copies to everyone who asks. This is much faster than rewriting the document each time, but means you need to make new photocopies when the original changes.

Preprocessors

Preprocessors in the Rails Asset Pipeline are tools that transform assets from one format to another before they're served to the browser. Common examples include Sass for CSS, CoffeeScript for JavaScript, and ERB for embedding Ruby in asset files.

# A .scss file (Sass preprocessor)
$primary-color: #4a90e2;

.button {
  background-color: $primary-color;
  &:hover {
    background-color: darken($primary-color, 10%);
  }
}

# A .coffee file (CoffeeScript preprocessor)
class User
  constructor: (@name) ->

  sayHello: ->
    "Hello, !"

🧠 Think of it like...

Language translators at an international conference. Just as translators convert speeches from one language to another so everyone can understand, preprocessors convert your assets from specialized languages (like Sass or CoffeeScript) into standard formats (like CSS or JavaScript) that browsers can understand.

Proc

A Proc is an object that encapsulates a block of code. It's similar to a block, but it can be saved as a variable, passed to methods, and called later. Procs are more flexible than blocks because they can be stored and reused.

# Creating a Proc
square = Proc.new { |x| x * x }

# Calling a Proc
square.call(5) # => 25

# Passing a Proc to a method
[1, 2, 3].map(&square) # => [1, 4, 9]

# Converting a block to a Proc
def with_logging(&block)
  puts "Before"
  result = block.call
  puts "After"
  result
end

with_logging { puts "During"; 42 } # => 42

🧠 Think of it like...

A recipe card that you can save, share, and use multiple times. Unlike verbal instructions (blocks) that you can only use once, a written recipe (Proc) can be saved and reused whenever you need it.

R

Rack Builder

Rack::Builder is a DSL (Domain Specific Language) for creating Rack application stacks. It provides a simple way to chain multiple Rack middleware together and map different URL paths to different Rack applications. Rails uses Rack::Builder internally to construct its middleware stack and handle routing.

# Using Rack::Builder to create a middleware stack
app = Rack::Builder.new do
  use Rack::CommonLogger
  use Rack::ShowExceptions

  map '/api' do
    run ApiApp.new
  end

  map '/' do
    run WebApp.new
  end
end

# The above is equivalent to this in a config.ru file:
use Rack::CommonLogger
use Rack::ShowExceptions

map '/api' do
  run ApiApp.new
end

map '/' do
  run WebApp.new
end

🧠 Think of it like...

A building contractor who coordinates different specialists. Just as a contractor brings together plumbers, electricians, and carpenters to build a house, Rack::Builder brings together different middleware components to build a complete web application stack. It ensures that each component is properly connected and that requests are routed to the right application based on the URL.

Rack Middleware

Rack Middleware are components that sit between the web server and your application, processing the request and response. Each middleware can modify the request before passing it to the next component, and can modify the response on the way back. Middleware are stacked in a pipeline, allowing for modular and reusable functionality like logging, authentication, caching, and more.

# A simple Rack middleware
class Logger
  def initialize(app)
    @app = app
  end

  def call(env)
    # Process request before passing to the next middleware
    puts "Request: #{env['REQUEST_METHOD']} #{env['PATH_INFO']}"

    # Call the next middleware in the stack
    status, headers, body = @app.call(env)

    # Process response before returning
    puts "Response: #{status}"

    # Return the response
    [status, headers, body]
  end
end

# Using the middleware in a Rails application
# In config/application.rb
module MyApp
  class Application < Rails::Application
    config.middleware.use Logger
  end
end

🧠 Think of it like...

An assembly line in a factory. Just as products move through different stations in an assembly line, with each station performing a specific task, HTTP requests and responses pass through a series of middleware components. Each middleware performs a specific function (like authentication or logging) before passing the request to the next component in the line.

Rack Protocol

The Rack protocol is a simple interface between web servers and Ruby web applications. It specifies that an application must be an object that responds to the 'call' method, takes a single hash parameter (the environment), and returns an array of three elements: HTTP status code, HTTP headers, and response body. This standardized interface allows Ruby web frameworks like Rails to be used with various web servers without modification.

# A simple Rack application
class HelloWorld
  def call(env)
    # Return [status, headers, body]
    [200, { 'Content-Type' => 'text/plain' }, ['Hello, World!']]
  end
end

# Using the application with Rack
require 'rack'
Rack::Handler::WEBrick.run HelloWorld.new

🧠 Think of it like...

A universal power adapter. Just as a universal adapter allows devices from different countries to plug into any power outlet, Rack provides a standard interface that allows any Ruby web application to connect to any Rack-compatible web server. This eliminates the need for custom adapters for each server-framework combination.

Rails on Rack

Rails on Rack refers to how the Ruby on Rails framework is built on top of the Rack interface. Rails uses Rack to handle HTTP requests and responses, allowing it to be compatible with any Rack-compliant web server. Understanding how Rails integrates with Rack helps developers customize the request/response cycle, add middleware, and optimize their applications.

# Rails application entry point (config.ru)
require_relative 'config/environment'
run Rails.application

# Inspecting the middleware stack
$ rails middleware

# Adding custom middleware in config/application.rb
module MyApp
  class Application < Rails::Application
    config.middleware.use MyCustomMiddleware

    # Insert at a specific position
    config.middleware.insert_before Rack::Runtime, MyMiddleware

    # Remove a middleware
    config.middleware.delete Rack::Runtime
  end
end

🧠 Think of it like...

A high-speed train running on standardized tracks. Rails is like the train (a powerful, feature-rich framework), while Rack provides the standardized tracks (interface) that allow the train to run on different rail networks (web servers). This standardization ensures that Rails can work with any Rack-compatible server without modification.

Read/Write Splitting

Read/Write Splitting is a database architecture pattern where read operations are directed to replica databases, while write operations are sent to a primary database. In Rails, this is implemented using database roles, allowing you to optimize performance by distributing the database load.

# In config/database.yml
production:
  primary:
    database: my_primary_database
    adapter: mysql2
  primary_replica:
    database: my_primary_database_replica
    adapter: mysql2
    replica: true

# In app/models/application_record.rb
class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true

  connects_to database: { writing: :primary, reading: :primary_replica }
end

# Rails automatically uses the appropriate connection
# Write operation - uses primary
Post.create!(title: "New Post")

# Read operation - uses replica
@posts = Post.all

# Force a specific role
ActiveRecord::Base.connected_to(role: :writing) do
  # This will use the primary database even for reads
  @posts = Post.all
end

🧠 Think of it like...

A library with separate reading rooms and a central book repository. Visitors can read books in any reading room (replicas), but new books can only be added to the central repository (primary). This allows many people to read simultaneously without crowding the central repository, while ensuring all new books go through a single controlled process.

RubyGems

RubyGems is Ruby's package manager. It allows you to download, install, and use Ruby libraries (gems) in your projects. RubyGems makes it easy to share code and functionality between Ruby developers.

# Installing a gem
gem install rails

# Using Bundler to manage gems
# In Gemfile:
source 'https://rubygems.org'
gem 'rails', '~> 7.0.0'
gem 'pg', '~> 1.1'

# Then run:
bundle install

🧠 Think of it like...

An app store for Ruby. Just as you might download apps from an app store to add functionality to your phone, you can download gems from RubyGems to add functionality to your Ruby projects.

Russian Doll Caching

Russian Doll Caching is a powerful caching technique in Rails that allows nested cache fragments to be automatically invalidated when any of their dependencies change. It's named after Russian nesting dolls because it involves nested cache blocks, where outer caches contain inner ones.

# Basic Russian Doll Caching example
<% cache ['v1', @post] do %>
  <%= render @post %>
  <% cache ['v1', @post, :comments] do %>
    <%= render @post.comments %>
    <% @post.comments.each do |comment| %>
      <% cache ['v1', comment] do %>
        <%= render comment %>
      <% end %>
    <% end %>
  <% end %>
<% end %>

🧠 Think of it like...

A set of Russian nesting dolls. If you change one of the inner dolls, you need to replace all the outer dolls that contain it. Similarly, if a nested cached item changes, all the caches that contain it must be invalidated too.

S

SQL Caching

SQL Caching in Rails is a feature that automatically caches the results of database queries within a single request. When the same query is executed multiple times in the same request cycle, Rails will use the cached result instead of hitting the database again, which can significantly improve performance.

# SQL caching is enabled by default in production
# and can be manually enabled in development:

# In a controller action
def index
  # First time: executes the SQL query
  @posts = Post.all

  # Second time: uses the cached result, no SQL query
  @same_posts = Post.all
end

# You can also manually control the cache
Post.cache do
  # All queries inside this block are cached
  Post.find(1)
  Post.find(1) # Uses cached result
end

# Clear the query cache
ActiveRecord::Base.clear_query_cache

🧠 Think of it like...

A waiter who remembers your order. If five people at a table all order the same dish, the waiter doesn't need to ask the chef five times - they just remember the recipe and preparation from the first time and deliver the same dish to everyone. Similarly, Rails remembers the results of SQL queries so it doesn't have to ask the database the same question repeatedly.

SQL Injection

SQL Injection is a type of security vulnerability that occurs when an attacker is able to insert malicious SQL code into a query that is then executed by the database. In Rails, this can happen when user input is directly interpolated into SQL queries without proper sanitization.

# Vulnerable to SQL Injection:
User.where("username = '#{params[:username]}'") # NEVER DO THIS!

# Safe from SQL Injection (using parameterized queries):
User.where("username = ?", params[:username])

# Even better, use hash conditions:
User.where(username: params[:username])

🧠 Think of it like...

Imagine you're filling out a form at a doctor's office. If the receptionist just takes whatever you write and enters it directly into their system without checking, you could write instructions that manipulate their database instead of providing your actual information.

Singleton Class

A Singleton Class (also called an eigenclass or metaclass) is a hidden class associated with a specific object. It allows you to define methods that are specific to that object, rather than to all instances of its class.

obj = Object.new

# Adding a method to obj's singleton class
def obj.hello
  "Hello from this specific object"
end

# Alternative syntax using the singleton class directly
class << obj
  def goodbye
    "Goodbye from this specific object"
  end
end

obj.hello # => "Hello from this specific object"
obj.goodbye # => "Goodbye from this specific object"

# Other objects of the same class don't have these methods
another_obj = Object.new
# another_obj.hello would raise NoMethodError

🧠 Think of it like...

A personal trainer. While everyone in a gym class (instances of a class) follows the same general workout, a personal trainer (singleton class) gives you specific exercises that only apply to you.

Sprockets

Sprockets is the Ruby library that powers the Rails Asset Pipeline. It handles the preprocessing, concatenation, minification, and compression of JavaScript, CSS, and other assets. Sprockets uses a directive system to manage dependencies and inclusion of assets.

# In Gemfile
gem 'sprockets-rails'

# In config/initializers/assets.rb
Rails.application.config.assets.precompile += %w( admin.js admin.css )

# In a JavaScript file using Sprockets directives
//= require jquery
//= require_tree ./modules

🧠 Think of it like...

A kitchen food processor with multiple attachments. Just as a food processor can slice, dice, blend, and puree food with different attachments, Sprockets processes your assets in various ways (compiling, concatenating, minifying) to prepare them for efficient delivery to the browser.

Symbol

A Symbol is an immutable name or string. Symbols are prefixed with a colon (:) and are often used as hash keys or to represent names. Unlike strings, identical symbols are the same object in memory, which makes them more efficient for certain operations.

# Creating symbols
:name
:"complex name"

# Symbols vs strings
"string".object_id == "string".object_id # => false
:symbol.object_id == :symbol.object_id # => true

# Using symbols as hash keys
person = { name: 'John', age: 30 }
person[:name] # => 'John'

🧠 Think of it like...

A name tag. Just as a name tag identifies a person with a simple label, a symbol identifies a concept or value with a simple, immutable name. And just as you only need one name tag per person, Ruby only needs one symbol object per name.

T

Thread

A Thread is a lightweight process that can run concurrently with other threads. Ruby supports multithreading, which allows you to perform multiple operations simultaneously. Threads share the same memory space but have their own execution stack.

# Creating a thread
thread = Thread.new do
  # Code to run in the thread
  puts "Thread started"
  sleep 2
  puts "Thread finished"
end

# Main thread continues executing
puts "Main thread continues"

# Wait for the thread to finish
thread.join

# Thread-local variables
Thread.current[:user_id] = 42

🧠 Think of it like...

A worker in a team. Just as multiple workers can work on different tasks simultaneously, multiple threads can execute different parts of your code at the same time. They all work for the same company (program) and share the same office space (memory), but each has their own desk and tasks.

U

URL Maps

URL Maps in Rack are a way to route different URL paths to different Rack applications or middleware stacks. They allow you to create a composite application where different parts of your website are handled by different applications. In Rails, URL mapping is handled by the router, but understanding the underlying Rack URL mapping helps in advanced routing scenarios.

# In a config.ru file
map '/api' do
  run ApiApp.new
end

map '/admin' do
  use AdminAuth
  run AdminApp.new
end

map '/' do
  run MainApp.new
end

# This routes requests to:
# - /api/* to ApiApp
# - /admin/* to AdminApp (with AdminAuth middleware)
# - All other requests to MainApp

🧠 Think of it like...

A postal sorting facility. Just as mail is sorted based on zip codes and delivered to different destinations, URL maps direct HTTP requests to different applications based on the URL path. Each application is like a different post office that handles mail for a specific area.

V

Variable

A Variable is a named storage location for data. Ruby has several types of variables, each with its own scope and purpose:
- Local variables: Start with a lowercase letter or underscore (_)
- Instance variables: Start with an at sign (@)
- Class variables: Start with two at signs (@@)
- Global variables: Start with a dollar sign ($)
- Constants: Start with an uppercase letter

# Local variable
name = "John"

# Instance variable
@age = 30

# Class variable
@@count = 0

# Global variable
$config = { debug: true }

# Constant
MAX_USERS = 100

🧠 Think of it like...

Different types of storage containers. Local variables are like personal notebooks (only accessible in a specific context), instance variables are like personal lockers (specific to an object), class variables are like shared cabinets (shared by all instances of a class), global variables are like public bulletin boards (accessible everywhere), and constants are like carved stone tablets (meant to be unchanging).

W

Webpacker

Webpacker is a Ruby gem that integrates Webpack with Rails applications. It provides a standard way to manage JavaScript, CSS, and other front-end assets in Rails. Webpacker helps organize modern JavaScript code with modules, transpilation, and bundling.

# In a Rails application with Webpacker

# JavaScript files are typically in app/javascript
# app/javascript/packs/application.js is the entry point

# In your views, you can include the pack:
<%= javascript_pack_tag 'application' %>
<%= stylesheet_pack_tag 'application' %>

# Import modules in your JavaScript files
import Rails from '@rails/ujs'
import Turbolinks from 'turbolinks'

Rails.start()
Turbolinks.start()

🧠 Think of it like...

A food processor for your JavaScript. You put in raw ingredients (your JavaScript files, CSS, images), and Webpacker processes them into a form that's optimized for consumption by browsers (bundled, minified, and with compatibility fixes).

Y

Yield

Yield is a Ruby keyword that calls a block passed to a method. It allows a method to temporarily transfer control to the block, execute the block's code, and then resume execution of the method. This enables powerful patterns like iterators and callbacks.

# A method that uses yield
def greet
  puts "Before the yield"
  yield
  puts "After the yield"
end

# Calling the method with a block
greet { puts "Hello from the block!" }

# Output:
# Before the yield
# Hello from the block!
# After the yield

# Yield with parameters
def with_value
  yield(42)
end

with_value { |value| puts "The value is #{value}" }

🧠 Think of it like...

A relay race baton handoff. The method runs until it reaches 'yield', then passes the baton (control) to the block. The block runs its code, then passes the baton back to the method, which continues running.

Z

Zeitwerk

Zeitwerk is the code autoloader used in Rails 6+ applications. It automatically loads Ruby classes and modules on-demand, eliminating the need for explicit require statements. Zeitwerk follows Ruby conventions for file naming and module nesting, making code organization more intuitive.

# With Zeitwerk, you don't need to require files explicitly

# If you have a file app/models/user.rb with:
class User
  # ...
end

# You can use it anywhere without requiring it:
user = User.new

# Zeitwerk also handles namespaces:
# app/services/payment/processor.rb maps to Payment::Processor

🧠 Think of it like...

A smart librarian who knows exactly where every book is shelved. When you ask for a specific book (class), the librarian (Zeitwerk) immediately fetches it for you without you having to know its exact location (file path).

Propose a New Term

Know a Ruby or Rails term that should be in our glossary? We'd love to hear from you!

Propose a New Term

Your contributions help make this resource better for everyone.

RubyCademy ©