0% found this document useful (0 votes)
4 views

High Performance PostgreSQL for Rails Beta Reliable Scalable Maintainable Database Applications Andrew Atkinson download

The document is a beta release of 'High Performance PostgreSQL for Rails' by Andrew Atkinson, aimed at enhancing skills in managing PostgreSQL databases for Ruby on Rails applications. It covers various topics, including database design, performance optimization, and maintenance strategies, while providing practical exercises. The book is still under development, with potential errors and updates available for download as the final version is completed.

Uploaded by

avadzigeysa
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views

High Performance PostgreSQL for Rails Beta Reliable Scalable Maintainable Database Applications Andrew Atkinson download

The document is a beta release of 'High Performance PostgreSQL for Rails' by Andrew Atkinson, aimed at enhancing skills in managing PostgreSQL databases for Ruby on Rails applications. It covers various topics, including database design, performance optimization, and maintenance strategies, while providing practical exercises. The book is still under development, with potential errors and updates available for download as the final version is completed.

Uploaded by

avadzigeysa
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 52

High Performance PostgreSQL for Rails Beta

Reliable Scalable Maintainable Database


Applications Andrew Atkinson pdf download

https://ebookname.com/product/high-performance-postgresql-for-
rails-beta-reliable-scalable-maintainable-database-applications-
andrew-atkinson/

Get Instant Ebook Downloads – Browse at https://ebookname.com


Instant digital products (PDF, ePub, MOBI) available
Download now and explore formats that suit you...

Designing Data Intensive Applications The Big Ideas


Behind Reliable Scalable and Maintainable Systems
Martin Kleppmann

https://ebookname.com/product/designing-data-intensive-
applications-the-big-ideas-behind-reliable-scalable-and-
maintainable-systems-martin-kleppmann/

Crafting Rails Applications Expert Practices for


Everyday Rails Development 1st Edition Jose Valim

https://ebookname.com/product/crafting-rails-applications-expert-
practices-for-everyday-rails-development-1st-edition-jose-valim/

PostgreSQL High Availability Cookbook 2nd Edition Shaun


M. Thomas

https://ebookname.com/product/postgresql-high-availability-
cookbook-2nd-edition-shaun-m-thomas/

Oil A Cultural and Geographic Encyclopedia of Black


Gold 2 volumes Li

https://ebookname.com/product/oil-a-cultural-and-geographic-
encyclopedia-of-black-gold-2-volumes-li/
Mastering Personal and Interpersonal Skills Key
Techniques for Effective Decision Making and Personal
Success 1st Edition Peter F. Haddon

https://ebookname.com/product/mastering-personal-and-
interpersonal-skills-key-techniques-for-effective-decision-
making-and-personal-success-1st-edition-peter-f-haddon/

Crossing the Rubicon The Decline of the American Empire


at the End of the Age of Oil Michael C. Ruppert

https://ebookname.com/product/crossing-the-rubicon-the-decline-
of-the-american-empire-at-the-end-of-the-age-of-oil-michael-c-
ruppert/

A Farewell to Arms Beyond the Good Friday Agreement


2Rev Ed Edition Michael Cox

https://ebookname.com/product/a-farewell-to-arms-beyond-the-good-
friday-agreement-2rev-ed-edition-michael-cox/

James Bridie Clown and Philosopher Helen L. Luyben

https://ebookname.com/product/james-bridie-clown-and-philosopher-
helen-l-luyben/

Developmental Neuroscience 2nd Edition Donald J. Cohen

https://ebookname.com/product/developmental-neuroscience-2nd-
edition-donald-j-cohen/
Green s Functions and Linear Differential Equations
Theory Applications and Computation 1st Edition Prem K.
Kythe

https://ebookname.com/product/green-s-functions-and-linear-
differential-equations-theory-applications-and-computation-1st-
edition-prem-k-kythe/
ß
Under Construction: The book you’re reading is still under
development. As part of our Beta book program, we’re releasing
this copy well before a normal book would be released. That
way you’re able to get this content a couple of months before
it’s available in finished form, and we’ll get feedback to make
the book even better. The idea is that everyone wins!

Be warned: The book has not had a full technical edit, so it will contain errors.
It has not been copyedited, so it will be full of typos, spelling mistakes, and the
occasional creative piece of grammar. And there’s been no effort spent doing
layout, so you’ll find bad page breaks, over-long code lines, incorrect hyphen-
ation, and all the other ugly things that you wouldn’t expect to see in a finished
book. It also doesn't have an index. We can’t be held liable if you use this book
to try to create a spiffy application and you somehow end up with a strangely
shaped farm implement instead. Despite all this, we think you’ll enjoy it!

Download Updates: Throughout this process you’ll be able to get updated


ebooks from your account at pragprog.com/my_account. When the book is com-
plete, you’ll get the final version (and subsequent updates) from the same ad-
dress.

Send us your feedback: In the meantime, we’d appreciate you sending us your
feedback on this book at pragprog.com/titles/aapsql/errata, or by using the links
at the bottom of each page.

Thank you for being part of the Pragmatic community!

The Pragmatic Bookshelf


High Performance PostgreSQL for Rails
Reliable, Scalable, Maintainable Database Applications

Andrew Atkinson

The Pragmatic Bookshelf


Dallas, Texas
Many of the designations used by manufacturers and sellers to distinguish their products
are claimed as trademarks. Where those designations appear in this book, and The Pragmatic
Programmers, LLC was aware of a trademark claim, the designations have been printed in
initial capital letters or in all capitals. The Pragmatic Starter Kit, The Pragmatic Programmer,
Pragmatic Programming, Pragmatic Bookshelf, PragProg and the linking g device are trade-
marks of The Pragmatic Programmers, LLC.
Every precaution was taken in the preparation of this book. However, the publisher assumes
no responsibility for errors or omissions, or for damages that may result from the use of
information (including program listings) contained herein.
For our complete catalog of hands-on, practical, and Pragmatic content for software devel-
opers, please visit https://pragprog.com.

For sales, volume licensing, and support, please contact support@pragprog.com.

For international rights, please contact rights@pragprog.com.

Copyright © 2023 The Pragmatic Programmers, LLC.

All rights reserved. No part of this publication may be reproduced, stored in a retrieval system,
or transmitted, in any form, or by any means, electronic, mechanical, photocopying, recording,
or otherwise, without the prior consent of the publisher.

ISBN-13: 979-8-88865-038-7
Encoded using the finest acid-free high-entropy binary digits.
Book version: B1.0—August 30, 2023
Contents

Change History . . . . . . . . . . . . ix

Preface . . . . . . . . . . . . . . xi

Part I — Getting Started


1. An App to Get You Started . . . . . . . . . 3
What Is Rideshare? 3
Active Record Schema Management Refresher 4
Installing Rideshare 6
Working With PostgreSQL Locally 10
Learning PostgreSQL Terminology 10
Learning SQL Terminology 11
Ruby on Rails Terminology 12
Conventions Used In This Book 13
You’re Ready 15

Part II — Design and Build


2. Administration Basics . . . . . . . . . . 19
Learning Meta Commands In psql With Rideshare 20
Modifying Your PostgreSQL Config File 22
Getting Started With Query Observability 23
Glancing At Current Lock Behavior 25
Generating Fake Data For Experiments 26
Rolling Back Schema Modifications 28
Exploring and Experimenting Safely In Production 29

3. Building a Performance Testing Database . . . . . 33


Downloading Production Data Dumps 34
Contents • iv

Replacement Values That Are Statistically Similar 37


Tracking Columns With Sensitive Information 39
Comparing Direct Updates and Table Copying Strategies 39
Starting An Email Scrubber Function 40
Implementing the Scrub Email Function 42
Understanding Table Copying Trade-Offs 45
Speeding Up Inserts For Table Copying 47
Using Direct Updates For Text Replacement 53
Performing Database Maintenance 54
Performing Modifications In Batches 55
What’s Next For Your Performance Database 57

4. Data Correctness and Consistency . . . . . . . 59


Multiple Column Uniqueness 60
Fixing Constraint Violations 62
Enforcing Relationships With Foreign Keys 63
The Versatile Check Constraint 64
Deferring Constraint Checks 67
Preventing Overlaps With An Exclusion Constraint 68
Creating Active Record Custom Validators 69
Significant Casing And Unique Constraints 72
Storing Transformations In Generated Columns 73
Constraining Values With Database Enums 74
Sharing Domains Between Tables 77
Automating Consistency Checks In Development 79

Part III — Operate and Grow


5. Modifying Busy Databases Without Downtime . . . . 83
Identifying Dangerous Migrations 85
Learning From Unsafe Migrations 85
Learning To Use CONCURRENTLY By Default 88
Adopting A Migration Safety Check Process 89
Exploring Strong Migrations Features 89
Locking, Blocking, and Concurrency Refresher 92
Preventing Excessive Queueing With A Lock Timeout 95
Exploring Lock Type Queues 96
Setting Statement Timeout 97
Avoiding Schema Cache Errors 98
Backfilling Large Tables Without Downtime 98
Contents •v

Backfilling And Double Writing 99


Separating Reads and Writes for Backfills 99
Specialized Tables For Backfills 100
Practicing Backfilling Techniques 101
Wrapping Up 102

6. Optimizing Active Record . . . . . . . . . 105


Preferring Active Record Over SQL 105
Query Logs To Connect SQL to App Code 106
Common Active Record Problems 107
Use Eager Loading To Reduce Queries 110
Eager Loading With .includes() 110
Prefer Strict Loading Over Lazy Loading 111
Optimizing Individual Active Record Queries 112
Save A SELECT With A RETURNING 113
Bounding Query Results Using LIMIT 114
Advanced Query Support In Active Record 115
Using Common Table Expressions (CTE) 116
Introducing Database Views for Rideshare 118
Creating the Search Result Model With Scenic 120
Improving Performance With Materialized Views 121
Reducing Queries With Active Record Caches 122
Prepared Statements With Active Record 123
Eliminating Slow Count Queries With Counter Caches 124
Performing Aggregations In the Database 126
Reduced Object Allocations With SQL In Active Record 127
Wrapping Up 128

7. Improving Query Performance . . . . . . . . 129


Logging Slow Queries With Active Support Notifications 130
Capture Query Statistics In Your Database 131
Rideshare Query Statistics 132
Introducing PgHero As a Performance Dashboard 133
Analyzing Query Execution Plans 135
Finding Missing Indexes 138
Logging Slow Queries 139
Automatically Gathering Execution Plans 140
Performing Maintenance First 141
Interpreting Index Scan Execution Plan Info 142
EXPLAIN Scan Nodes and Bitmap Scans 143
Adding Query Boundaries With Filtering and LIMIT 144
Contents • vi

Performing Fast COUNT() Queries 145


Using Code and SQL Analysis Tools 147
Wrapping Up 147

8. Optimized Indexes For Fast Retrieval . . . . . . 149


Generating Data for Experiments 150
Transforming Ruby to SQL 153
Why Are My Indexes Not Being Used? 154
Using Single Column And Multiple Column Indexes 154
Understanding Index Column Ordering 155
Indexing Boolean Columns 156
Transform Values with an Expression Index 157
Using GIN Indexes with JSON 158
Using GIN Indexes for Full Text Search 162
Using Partial Indexes 165
Using BRIN Indexes 167
Using Indexes In Less Common Ways 170
Using Covering Indexes 171

9. High Impact Database Maintenance . . . . . . . 175


Basics of Autovacuum 176
Tuning Autovacuum Parameters 177
Rebuilding Indexes Without Downtime 179
Running Manual Vacuums 180
Simulating Bloat and Understanding Impact 181
Removing Unused Indexes 183
Removing Duplicate And Overlapping Indexes 184
Removing Indexes On Insert Only Tables 186
Scheduling Jobs Using pg_cron 186
Monitoring pg_cron Scheduled Jobs 188
Conducting Maintenance Tune-Ups 189

10. Handling Errors From Increased Concurrency . . . . 191


Monitoring Database Connections 192
Managing Idle Connections 194
Setting Active Record Pool Size 195
Using the Active Record Connection Pool 195
Running Out Of Connections 196
Working With PgBouncer 199
Choosing A PgBouncer Pooling Mode 201
Identifying Connection Errors and Problems 202
Contents • vii

More Lock Monitoring With pg_locks 204


Monitoring Row Locks 204
Finding Lock Conflicts 205
Using PgBadger For Lock Analysis 206
Active Record Optimistic Locking 206
Using Advisory Locks 207
Wrapping Up 208

Part IV — Optimize and Scale


11. Scalability of Common Features . . . . . . . 211

12. Working With Bulk Data . . . . . . . . . 213

13. Scaling With Replication And Sharding . . . . . . 215

14. Boosting Performance With Partitioning . . . . . 217

Part V — Advanced Uses


15. Advanced Usage and What’s Next . . . . . . . 221

A1. Installation Guides . . . . . . . . . . . 223

A2. psql Client . . . . . . . . . . . . . 225

A3. Getting Help . . . . . . . . . . . . 227


Change History
The book you’re reading is in beta. This means that we update it frequently.
Here is the list of the major changes that have been made at each beta release
of the book, with the most recent change first.

B1.0: August 30, 2023


• Initial beta release.

report erratum • discuss


Preface
If you’re looking to improve your skills with PostgreSQL for Ruby on Rails
you’ve come to the right place. In this book you’ll work on exercises from
practical problems that will help you grow your career.

Maybe your application has grown in popularity and you’ve got performance
problems. Maybe your database has ballooned in size and you aren’t sure
how to manage the growth. In the market, the traditional Database Adminis-
trator role is declining in popularity while there are more database-backed
web applications than ever. Organizations from startups to huge companies
choose PostgreSQL as a mission critical database to build their businesses
on. Operator challenges, especially under high growth and high query volume,
can put a lot of pressure on the engineering team. Why not be the team
member who takes on these challenges?

Get ready to develop useful skills for operating PostgreSQL that you can
immediately put to use. You’ll use the latest versions of PostgreSQL and Ruby
on Rails. You’ll work on making your applications and databases faster, more
reliable, and more resilient. As you work towards mastery of high performance
operations, you’ll raise the bar for operational excellence for your PostgreSQL
database and your engineering team.

As you go through the book’s exercises, you’ll work with a real Rails application
and database schema that you can see and continue to evolve as a test lab
for your skill development. You’ll populate millions of rows of data to work
with, to help simulate your production workload. In addition to the core
functionality of PostgreSQL and Ruby on Rails, you’ll be working with 50
Ruby gems and PostgreSQL extensions.

Who Is This Book For?


This book is for developers looking to improve their skills with PostgreSQL
and Ruby on Rails. Whether you’re working on consumer scale Internet
applications or enterprise B2B Software as a Service (SaaS), scaling PostgreSQL

report erratum • discuss


Preface • xii

and Rails application codebases is mission critical for the success of your
business. Your team members expect you to both build with and operate
these technologies, managing huge data growth, shifting business priorities,
and operating reliable and cost efficient infrastructure.

If your job responsibilities or career aspirations include any of the following


descriptions, you’ve come to the right place:

• Ruby on Rails Application Developers improving their PostgreSQL


knowledge and skills
• PostgreSQL Database Administrators (DBAs) learning about Ruby on Rails
and Active Record
• Infrastructure Engineers developing SQL knowledge and PostgreSQL
knowledge for Replication, Parameters, Maintenance, and Partitioning
• Database Reliability Engineers (DBRE) implementing Sharding, Replication,
Partitioning, and Parameter Optimization
• SQL developers experienced with other database engines looking to learn
PostgreSQL
• Database engineers working with MySQL looking to learn PostgreSQL
• Web Application Developers using other full-stack web frameworks like
Laravel1 or Django,2 looking to learn Ruby on Rails and Active Record
• Data Engineers working with OLAP databases interested in Replication
and Change Data Capture (CDC) with PostgreSQL and OLTP use cases
• Engineers looking to get a promotion to senior levels with improved
database skills

Here you’ll work exclusively with the open source community distribution of
PostgreSQL. Sticking with locally installed community distribution of Post-
greSQL allows readers to gain confidence by developing and testing locally.
After getting in some practice, readers can take their skills into production.

The focus is on Transactional workloads, also called Online Transaction


Processing or (OLTP), and not Analytical workloads. OLTP workloads are the
types of queries you’d see in a web application that is user facing.

What’s Not Covered In This Book?


This book will help you a lot but it doesn’t cover everything. It is not an
introduction to PostgreSQL or Ruby on Rails. Books like PostgreSQL: Up and
Running3 are intended to help get readers started.

1. https://laravel.com
2. https://www.djangoproject.com
3. https://www.oreilly.com/library/view/postgresql-up-and/9781449326326/

report erratum • discuss


What’s Not Covered In This Book? • xiii

Pragmatic Programmers has lots of excellent books on Ruby on Rails. Agile


Web Development with Rails 74 would be a great book to go through first if
you’re new to Ruby on Rails. This book will help you build a good foundation
with Ruby on Rails and Active Record. For readers that wish to strengthen
their skills with the Ruby programming language, considering purchasing
and reading Programming Ruby 3.2 (5th Edition).5

Internals of PostgreSQL are not covered beyond some basics as needed for a
chapter. Multiversion Concurrency Control (MVCC) and Isolation Levels for
example are introduced with some basic information and readers are direct
to the PostgreSQL documentation for more information.

User Administration, Roles, and Privileges are not covered. The GRANT command
and Security concepts like Row Level Security (RLS) and Policies are not cov-
ered.

Readers will set up multiple PostgreSQL instances, however High Availability


(HA) concepts like replication with Availability Zones (AZ) and Regions, or
Disaster Recovery (DR) implementations are outside the scope of this book.

For concepts like Recovery Time Objectives (RTO) and Recovery Point Objec-
tives (RPO), consider the book Database Reliability Engineering6 which
focuses on building reliable database systems.

Database Backups are critical. Your organization must collect Snapshots


automatically and be able to restore a database server instance to a previous
backup if disaster strikes. However, backups and restores are also outside
the scope of this book beyond some basics.

In the broader PostgreSQL ecosystem, there are many options beyond what
is supported in the open source community distribution where you’ll run
PostgreSQL on your local server instance. There are PostgreSQL forks, Post-
greSQL compatible databases, and PostgreSQL extensions that make very
significant modifications to how PostgreSQL operates. For example, the Citus
11.1 open source release7 modifies PostgreSQL as an extension. Although
extensions like Citus do offer portions of their offerings as open source soft-
ware, in general forks and different databases engines with compatibility are
outside the scope of this book.

4. https://pragprog.com/titles/rails7/agile-web-development-with-rails-7/
5. https://pragprog.com/titles/ruby5/programming-ruby-3-2-5th-edition/
6. https://www.oreilly.com/library/view/database-reliability-engineering/9781491925935/
7. https://www.postgresql.org/about/news/announcing-citus-111-open-source-release-2511/

report erratum • discuss


Preface • xiv

Ruby on Rails Skills Are In Demand


In the piece called “Big Transitions in the Tech Industry” covering Hired’s
2023 State of Software Engineers Survey,8 Ruby on Rails was the most sought-
after skill.
Ruby on Rails surfaced as the most in-demand skill for software engineering roles,
creating 1.64x more interview requests for the developers proficient in it.

Ruby on Rails is a great way to build PostgreSQL database applications. Ruby


on Rails has a Rails Guides page that is dedicated to showing how to use
Active Record with PostgreSQL.9 Some of the capabilities are exclusive to
PostgreSQL.

In the earlier days of Ruby on Rails and the Active Record ORM there was an
emphasis on portability, where web applications might migrate from one
database management system to another. Portability has been deemphasized
over the years. Community blog posts and conference talks regularly feature
capabilities that are exclusive to PostgreSQL.

Rails continues to add support for PostgreSQL capabilities to each new release.
Generated Columns from PostgreSQL 12 were added as Virtual Columns10
to Active Record.

In Rails 7.1 support for Common Table Expressions (CTE) queries were added
to Active Record.

These are exclusive or advanced database features that weren’t supported in


the past, but have been added to the core framework. These are the kinds of
topics you’ll find as you read on.

With native support for Multiple Databases, Ruby on Rails and Active Record
can be used with multiple PostgreSQL databases working together. Multiple
databases can be paired up using physical replication for Read and Write
splitting, or multiple writeable databases can be used from the application
for application level sharding. You’ll see and configure both of these.

We know skills with Ruby on Rails are in demand. What about PostgreSQL?

PostgreSQL Is A Popular Award Winner


You’ve made a great choice to invest your time learning PostgreSQL.

8. https://hired.com/state-of-software-engineers/2023/
9. https://guides.rubyonrails.org/active_record_postgresql.html
10. https://blog.saeloun.com/2022/01/25/rails-7-postgres-support-for-generated-columns.html

report erratum • discuss


PostgreSQL Is A Popular Award Winner • xv

For deployed Ruby on Rails applications, PostgreSQL is the #1 most popular


database according to the 2022 Ruby on Rails Community Survey with data
from 2009 through 2022.11

Besides the Rails Hosting Survey, the DB-Engines Ranking12 ranks the most
popular databases in the world. PostgreSQL has been a three-time #1 Winner
there in 2017, 2018, and 2020.

In 2021, PostgreSQL was the second most popular database, being a runner-
up to Snowflake.13

In 2022, PostgreSQL was the winner of the third most popular database.
Snowflake and Google BigQuery14 were #1 and #2 but neither are used for
OLTP.

The 2022 Stack Overflow Developer Survey15 gathered input from nearly
50,000 Professional Developers. When the developers were asked what
database they used most, PostgreSQL took the #1 spot.

Your investment in yourself building skills with PostgreSQL and Ruby on


Rails is a smart career move. These are very popular technologies that are in
high demand, used by small startups to giant corporations, being continually
improved year after year.

The future is very bright for PostgreSQL and Ruby on Rails!

11. https://rails-hosting.com/2022/#databases
12. https://db-engines.com/en/ranking
13. https://www.snowflake.com
14. https://cloud.google.com/bigquery
15. https://survey.stackoverflow.co/2022/#most-popular-technologies-database-prof

report erratum • discuss


Part I

Getting Started
CHAPTER 1

An App to Get You Started


Welcome! PostgreSQL and Rails are mature, powerful, and modern technolo-
gies. If you’re here to level up your skills using these technologies together,
you’ve picked up the right book.

The best way to learn is from hands on practice and experimentation. Here
you’ll work on exercises using practical examples, with a Rails API app con-
nected to PostgreSQL. You may want to challenge yourself on topics you’re
familiar with to build your own examples. Growth happens when solving
challenges just beyond your current skill level.

In this chapter, you’ll primarily get things installed and set up. You may have
a lot of experience with Ruby on Rails and less or none at all with PostgreSQL.
On the PostgreSQL side, you may be an experienced administrator but know
little about Ruby on Rails, or perhaps use another popular web framework.
Here you’ll get information wherever you fall in those skill areas.

The Ruby on Rails app you’ll use here is called Rideshare, and it’s proudly
configured to work with PostgreSQL. This is a open source Rails application
that’s available to download from GitHub.

Rideshare serves as a demonstration application both for Rails and Active


Record concepts, and for PostgreSQL concepts. When the topic involves
working directly with PostgreSQL, you’ll use the Rideshare database. When
the topic is a Rails topic, you’ll work with the Rideshare Ruby codebase.

What’s the Rideshare app all about?

What Is Rideshare?
Rideshare is an API-only web application that implements a portion of a fic-
tional ridesharing service. Think of Uber or Lyft. Imagine there could be mil-

report erratum • discuss


Chapter 1. An App to Get You Started •4

lions of riders booking trips provided by thousands of drivers in cities all


around the world.

Although a global ridesharing application would likely have a very large


codebase covering dozens or hundreds of models and database tables,
Rideshare has less than ten models and tables. The portion of the domain
model is a small core or sample that’s needed mainly for demonstration pur-
poses in examples and exercises you’ll see.

The core nouns you’ll work with are Drivers, Riders, Trips, and Trip Requests.
These are Active Record models that are backed by database tables.

As a refresher or if you’re newer to Rails, Active Record is the Object Relational


Mapper (ORM) framework for Ruby on Rails. Active Record connects object
oriented Ruby classes as application code, to the persistence layer. Active
Record Objects are instantiated in memory and when they’re saved or
updated, a corresponding INSERT or UPDATE is sent to PostgreSQL.

Active Record works with many naming conventions that are important to
know. Models use a singular form for names like “Driver” in memory but by
convention are persisted into a table with a pluralized name like drivers. The
Convention Over Configuration design principle that’s a code aspect of Ruby
on Rails means that things like a table name in a model does not need to be
configured explicitly.

Rideshare has an Entity Relationship Diagram (ERD) available as a PDF in the


root directory of the project. The ERD is automatically updated when schema
changes are made. See the footnote with a link to the ERD where you can
visualize the database tables and their relationships.1

Active Record Schema Management Refresher


Active Record tracks database schema changes in a file. The file may be in a
Ruby format or a SQL format. Rideshare uses the SQL format. After every
schema modification is made, the Rideshare database schema is dumped
into the file db/structure.sql, which is version controlled. This file will always have
the latest version of the schema.

When you’re working with a new Rails application, explore the db/structure.sql
file and any available diagrams like ERDs, to begin to learn about the tables,
indexes, and constraints.

1. https://github.com/andyatkinson/rideshare/blob/master/erd.pdf

report erratum • discuss


Active Record Schema Management Refresher •5

If you’re newer to Rails, you might be wondering how changes are captured
in the db/structure.sql file. When a developer makes a schema modification,
behind the scenes Ruby on Rails when configured for PostgreSQL uses pg_dump
to dump the table structure to db/structure.sql.

If you’ve used a schema modification management tool like Flyway or


Liquibase, Active Record Migrations are going to be somewhat similar. In
Ruby on Rails, Active Record is built-in and is the way developers evolve the
schema.

Each modification is called a “Migration”, which is an overloaded term. In


Rails a Migration is a versioned Ruby file in the db/migrate directory. Rails
Migrations use an Active Record API that maps Ruby methods to SQL DDL
changes.

Within the Ruby source code file, schema modifications can be written in SQL
as well. Do Rails Migration files only contain structural changes, aka Data
Definition Language (DDL)? No, there aren’t any limitations on them, so
developers can perform Data Modification Language (DML) statements in the
form of inserting, updating, or deleting data. However, it’s considered a good
practice to use Migrations only for DDL and use Rake tasks or other mecha-
nisms for DML.

Does the db/structure.sql contain only structural data about the schema?
Although nearly all of the content of the file is purely structural, there is one
exception. At the bottom of the file there is “data”. The versioned Migration
files each have a unique number. The number is inserted into the developer’s
database when the Migration runs.

How is this tracked then? When the structure file is dumped, it’s dumped
based on the developer’s database, so any migrations that have been applied
there are dumped as INSERT statements. The schema migrations are dumped
as INSERT statements so that the database structure can be replicated on
another database by running bin/rails db:schema:load.

What this task does is load the content from the structure file and then insert
all the same migration versions into the destination database. That way if
another migration comes in after that one with a version number that doesn’t
exist, the database knows which versions have already been applied and will
apply only the new ones.

That was a quick refresher on how Active Record Migrations manage the
PostgreSQL database structure, how developers make incremental schema
modifications, and how those modifications are tracked.

report erratum • discuss


Chapter 1. An App to Get You Started •6

When you clone the Rideshare application and “migrate” (a verb in Rails
speak) the database, you’ve evolved your database schema to be in sync with
the latest production version.

Now that you have an idea of what the Rails application is, how the database
structure evolves and how to get a copy of the structure, you’ll want some
data.

You’ll use a couple of ways to get data into your database. To make it easy
to get started, you can use a pre-made data dump that can be downloaded
and loaded.

Then you’ll learn how to populate even more data via scripts that are part of
the Rideshare codebase.

It’s time to get Rideshare set up locally so you can explore the source code
and start the database server and web server.

Installing Rideshare
Begin by installing the dependencies needed to run Rideshare. Once the
dependencies are installed you’ll install the Rideshare application.

The examples here were developed on Mac OS, using the latest released ver-
sions of Ruby on Rails and PostgreSQL at the time of writing; these are listed
below.

• Mac OS Ventura
• Ruby on Rails 7 (Released 2021)
• PostgreSQL 15 (Released 2022)

Run the rails executable that’s part of the application by running bin/rails from
the root directory of Rideshare. You’ll use bin/rails to run commands like console,
server, and runner. You might see instructions to install Rails using gem install
rails. This method will make a rails executable available, but don’t use this
version for these exercises.

If you’re an experienced Rails application developer and PostgreSQL user,


you may be able to skip the next few sections.

If you’re less experienced with Ruby on Rails or with PostgreSQL, need a


refresher, or prefer to make sure everything is installed upfront correctly, go
through the instructions below to get everything configured on your local
development computer.

By the end you’ll have Rideshare fully running locally for development, con-
nected to a PostgreSQL database server instance.

report erratum • discuss


Installing Rideshare •7

Installing PostgreSQL on Mac OS


PostgreSQL can be installed in a variety of ways on Mac OS. The recommended
method is to use PostgresApp https://postgresapp.com. This is a native Mac OS
application. The installation process is the same for any installation with a
.dmg extension. Download the file using a browser, and double click it to start
the installation process.

Installing PostgreSQL using Homebrew or another method is also perfectly


fine. If you’re comfortable doing that, go for it.

Along with the PostgreSQL server installation, you’ll get additional PostgreSQL
Client Applications like pg_dump and psql2.

After installing PostgreSQL in one of the ways above, check the versions of
your client programs. This helps you verify they’re installed properly. Run
the following commands from your Terminal.
psql --version

pg_dump --version

With your PostgreSQL server instance started, open up your terminal and
type psql to connect to a default database that matches your OS username,
as a user (role) that’s your username. If your Mac OS username is andy (type:
whoami) without any arguments to psql, it will try and connect to a database
called andy with a user andy. If you see a psql prompt, you know you’re con-
nected. You may type SELECT current_database(); to view the current database
you’re connected to. Type \q to quit.

With your PostgreSQL server instance running, and being able to connect to
it for any database, you’re ready to proceed to work on getting the Ruby lan-
guage installed, and then the Rideshare Rails app installed.

Installing and Configuring Your Ruby Environment


Rideshare is a Ruby application, so you’ll need Ruby running on your com-
puter. From your Terminal, type ruby -v to see if you already have a version of
Ruby installed. Regardless, you’ll need the specific version that’s supported
by Rideshare. To find the specific version, Ruby apps have a convention to
place the version in a file in the root directory called ~/.ruby-version. Ruby Version
Managers were created to help you install and manage multiple versions of
Ruby installed at the same time. When a version is detected, the version
manager should automatically switch to that version.

2. https://www.postgresql.org/docs/current/reference-client.html

report erratum • discuss


Chapter 1. An App to Get You Started •8

The Ruby version manager called rbenv3 is a good choice. In this section you’ll
install rbenv and the version of Ruby that’s needed for Rideshare.

After Ruby is installed you’ll install the Bundler gem.4 Bundler will take care
of all the other dependencies needed. If you’re new to Rails it may be a little
daunting to get started, but this combination of Ruby Version, Bundler, and
running bundle install to install all the other gems needed is a common pattern.

In Ruby, third party shared library code is packaged and managed as a Ruby
gem. Ruby gems have an official website and repository, https://rubygems.org,
where you’ll find loads of gems and some statistics about their usage.

The instructions below are minimal. Extended instructions can be found in


the Installation Guides Appendix. Instructions will be maintained at
https://github.com/andyatkinson/development_guides as well.

Ruby on Rails and PostgreSQL are supported in local development for both
Linux and Windows, but you’ll need to find your own installation and devel-
opment guides for those.

On Mac OS, a popular package manager called Homebrew5 is the recommend-


ed way to install the Ruby Version Manager rbenv.

Install Homebrew using the latest available instructions at https://brew.sh. For


Homebrew you’ll work from your Terminal program running commands that
start with brew. When Homebrew is installed run brew -v and verify that it is
version 4 or newer.

Now you’re ready to install the Ruby version manager.

Run the following brew command from your terminal to install rbenv and ruby-
build.

brew install rbenv ruby-build

To verify these are installed, you may run rbenv --version and ruby-build --version.

With rbenv installed and Ruby versions available, you’re ready to install the
Ruby version needed for Rideshare.

3. https://github.com/rbenv/rbenv
4. https://bundler.io
5. https://brew.sh

report erratum • discuss


Installing Rideshare •9

Installing the Rideshare Application


To install Rideshare, work from your terminal and use git to clone the appli-
cation source code. Run git --version to confirm you’re running at least version
2.

1. Download the application source code by typing cd to navigate to your


project source code directory. For example, that might be cd ~/Projects. From
there, run git clone https://github.com/andyatkinson/rideshare.git

2. Once cloned, change into the Rideshare by typing cd rideshare

If you type pwd you should now be located in a directory like


/Users/andy/Projects/rideshare.

3. From there, you’re ready to install the Rideshare gems.

Type ruby -v and confirm the version matches the version in .ruby-version,
which was 3.2 at publication time. Install the bundler gem by typing gem
install bundler. This is the one gem you’ll install using gem install. Type bundler
--version to confirm version 2 or greater is installed.

With bundler installed, you’re ready to use it to install the Rideshare


gems. From the directory, type bundle install. This command installs Rails
and all the gems needed to run the application.

If you run into errors, please open an Issue on the project. A common
error occurs when installing gems like pg that have native code dependen-
cies, and the native code is not accessible. If you run into issues installing
the pg gem, see the Appendix for more information.

4. If all gems were installed successfully, you’re ready to set up the database.
From your terminal:

Use bin/rails db:create to create the development and test databases. The
PostgreSQL server must be running. Using this technique will create a
database role (user) named the same as your Mac OS user.

5. You now have the development database rideshare_development installed


locally and ready to use.

Installation is now complete. To further verify your installation, you may


run bin/rails db:migrate and confirm no pending migrations exist. You may
also wish to run the test suite for Rideshare for additional verifications.

6. To run the test suite for Rideshare, run bin/rails test in the Rideshare
directory from your terminal.

report erratum • discuss


Chapter 1. An App to Get You Started • 10

With Rideshare now installed and configured, you can begin to work with
your local PostgreSQL database.

Working With PostgreSQL Locally


If you’re an experienced PostgreSQL user you may wish to skip this section.

In the exercises here you’ll work exclusively using your local version of Post-
greSQL running the open source community distribution. You’ll get some
repetition in by regularly developing and testing in your local database. Your
local PostgreSQL database will have less functionality compared with modern
cloud hosted PostgreSQL instances, but it will be less complex and you’ll have
full control over it. You’ll use your local instance to develop skills you can
take with you into your production instance.

You’ll view log files, modify parameters, and start and stop your server
instance. Since you’re working locally on PostgreSQL, any queries or processes
are in your control and you may restart it at will. In production a database
restart requires careful planning and is generally avoided. Thus, you’ll practice
“reloading” configuration changes where possible to avoid restarts.

PostgreSQL is an extensible database. Here you’ll be limited to open source


PostgreSQL only, and you’ll work with extensions from the PostgreSQL
“ecosystem”. Extensions expand the core functionality. The extensions featured
here have broad support from the major PostgreSQL cloud providers. If you’re
self-hosting PostgreSQL you can of course install and configure any extensions
that you wish.

With that in mind, let’s jump into some PostgreSQL terminology.

Learning PostgreSQL Terminology


PostgreSQL is an object relational database. If you’re a programmer and are
familiar with Object Oriented Programming (OOP) then you might think of
objects like Ruby classes and inheritance hierarchies.

In PostgreSQL, database objects are things like tables, indexes, schemas,


column defaults, or constraints. Objects in Ruby and objects in PostgreSQL
refer to different things.

Databases have a LOT of terminology to familiarize yourself with. Newer


database users may benefit from a terminology glossary to begin to digest
some of the database specific terminology. Early and frequent exposure to
terms is important, so there are terminology guides in most chapters that
provide a short, simple definition for each term.

report erratum • discuss


Learning SQL Terminology • 11

Some terms you’ll run across are relations, tuples, bloat, and the optimizer.

A relation refers to a table. Tuples are versions of rows in tables. Bloat has to
do with inefficient data layout, where data is stored in a fragmented way and
this fragmentation can add latency to operations. These very brief definitions
are a starting point for exposure to these terms.

Some basic information on PostgreSQL data storage internals is useful. There’s


a lot more that we won’t discuss.

In PostgreSQL, data is laid out in pages. Data cannot be split across pages.
Data is stored efficiently when there are minimal gaps and data that is
accessed resides within a single page. Data that’s in a single page requires
fewer disk operations compared with accessing data that is split across mul-
tiple pages.

Another concept on data layout is correlation. Correlation refers to the rela-


tionship between how data resides on disk and how the data is ordered in a
query. High correlation means they’re similar and low correlation means they
are dissimilar.

PostgreSQL works whether data is stored efficiently or not. Data may not fit
in a single page, may be split across pages, and there may be a low correlation
for a query. You will explore these concepts.

Next let’s look at some SQL terminology.

Learning SQL Terminology


SQL has loads of terms as well, and much of it is not specific to PostgreSQL.

SQL is a declarative language. As a programmer, you declare to PostgreSQL


what results you want and PostgreSQL will figure out the best plan to get
them.

You specify the columns from the tables you want, and PostgreSQL determines
an optimized retrieval algorithm using knowledge of the data layout, database
objects, available hardware resources, and more.

PostgreSQL creates query execution plans on the fly to fulfill what you’ve asked
for. Multiple plans are pitted against one another. The plans are formed using
estimates about data in tables, so the plans aren’t always flawless but are
generally pretty good. As the programmer, you can see what PostgreSQL is
planning and influence it. You’ll learn more about that later on.

This plan evaluation process is conducted nearly instantly by the query exe-
cution planner, which is also referred to as the optimizer.

report erratum • discuss


Exploring the Variety of Random
Documents with Different Content
Bessie looked up suddenly. It seemed to her that John's heart
had done a funny thing; that it staggered and missed a beat.
But John ignored her look. His face was set and stubborn. He
changed his position slightly and gathered her yet more
determinedly in his arms, so that Bessie felt again how strong he
was, and how much it means to woman's life to add a strength like
that.
"Do you know, John," she prattled presently, out of the
deepening bliss which this enormous sense of security inspired, "do
you know that I used to fear for you? For me rather! To fear," she
exclaimed with a happily apologetic little laugh, "that you might fall
in love with Marien Dounay!"
But the laugh ended in a choke of surprise, when Bessie felt the
body of the big man shiver like a tree in a blast.
"Why? Why? What is the matter, John?" she asked in helpless
bewilderment, for the odd face with a profile like a mountain had
taken on a look of pain, and while she questioned him, he put her
from him and with a low groan sank down upon the bench.

* * * * *

The little summer house was still undisturbed by the rude, annoying
outer world; but its atmosphere had subtly changed. A chill wind
blew through the shrubbery and the fragrance of bush and flower
was gone. Even the sun, as if he could not bear to look, had
dropped behind the hill; for something had edged between the
lovers.
Bessie's artless words made John remember as very, very near,
what, during this delicious hour in her presence, had seemed to be
worlds and worlds behind him, in fact made him feel his shame and
guilt so deeply that he could no longer hold her in his arms. Then
the story of his infatuation for Marien Dounay came out, as he had
always felt it must, sometime, for the purging of his own soul, even
if it were she who would suffer most,—the old, old law of vicarious
suffering again!
Bessie listened with white, set face, while John resolutely spared
himself nothing in the telling, but when the look of hurt and pain
took up its abode permanently in those mild blue eyes, a feeling of
yet more terrible misgiving overtook him and he would have checked
the story if he could. But once started, his natural shrinking from
hypocrisy compelled him to tell the truth.
"You can never know how I have reproached myself for it," he
concluded. "I have suffered agonies of remorse. Wild with love of
you, and the impulse to declare that love, I have stayed away six
months. It seemed to me at first that I could hardly get my own
consent to come at all from her to you; that I must doom myself to
perpetual loneliness to expiate my sin. And yet, Bessie," John made
the mistake of trying to extenuate, "it was probably not altogether
unnatural, knowing man as I begin to know him."
To the young girl, facing the first bitter disillusionment of love, it
came like a flash of intuition that this last was true; that men were
like that—all men! They were mere brutes! This intuition maddened
the girl, and her disturbed emotions expressed themselves in a burst
of flaming anger.
"You may go back to Marien Dounay," she exclaimed hotly. "I do
not want her left-overs."
"But," protested John, with something of that sense of injury
which a man is apt to feel if forgiveness does not follow soon upon
confession, "you do not understand!"
"I understand," retorted Bessie with blazing sarcasm, "that you
fell hopelessly in love with this woman; that you embraced her,
kissed her, worshipped the ground she trod on; that you proposed to
marry her almost upon the spot; that she refused you and drove you
from her; that for a month you wrote me letters of hypocritical
pretense; that when she finally not only repulsed you but revealed
herself to you as a woman without character, you considerately
revived your affections for me."
John felt that in this storm of words some injustice was being
done him; yet he could not deny that such an outburst of wrath
upon Bessie's part was natural, and he humbled himself before the
blast.
In the vehemence of her demonstration, Bessie had arisen, and
after the final word stood with her back to her lover, looking out
upon the little lake which suddenly seemed a frozen sheet of ice.
"Bessie!" John murmured huskily, after an interval.
"Don't speak to me, don't!" she commanded hoarsely, without
turning her head.
John obeyed her so humbly and so completely that she began
to wonder if he were still there, or if he had sunk through the
ground in the shame and mortification which she knew well enough
possessed him.
When she had wondered long enough, she turned and found
him not only there but in a pose so abject and utterly remorseful
that her heart softened until she felt the need of self-justification.
"You were my god," she urged. "You inspired me! I worshipped
you! I thought you were as fine a man as my own father—and finer
because you had a finer ambition. I thought you were grand, noble,
strong!" Bessie stopped with her emphasis heavy upon the final
word.
"Is not the strong man the one who has found in what his
weakness lies?" John pleaded humbly.
But as before, his attempt at palliation seemed to anger her
unaccountably, and she turned away again with feelings too intense
for utterance—with, in fact, a dismal sense of the futility of
utterance. She wanted to get away from John. She wished he would
not stand there barring the door. She wished he would go while her
back was turned. A sense of humiliation greater than had possessed
him, she was sure, had come over her. If the lake in front had been
sixty feet deep instead of six inches, she might have flung herself
into it.
"But you love me!" pleaded John from behind her, his voice
coming up out of depths.
"Do you think I would care how many actresses you lost your
dizzy head over if I didn't?" retorted Bessie petulantly, and instantly
would have given several worlds to recall the speech.
"No! No!" she continued, stamping her foot angrily, "I don't love
you, I love the man I thought you were."
"All the same, I love you," groaned John, rising up to proclaim
his passion hoarsely and then flinging himself again upon the bench,
where with head hanging despondently, he continued: "I love you,
and I don't blame you for hating me, and you can punish me as long
as you want and in any way you want. You can even try to fall in
love with some one else if you like. Marry him if you want to. I love
you, and I'll keep on loving you. No punishment is too great for the
thing I've done."
The effect of this speech on the outraged Bessie was rather
alarming to that indignant young lady. When John began to heap the
reproaches higher upon himself, she felt a return to sympathetic
consideration for him that was so great she dared not trust herself to
hear more of them.
"Take me home!" she commanded hurriedly, walking swiftly by
him, but with scrupulous care that the swish of her white skirts
should not touch the bowed head as she passed, and no more
trusting herself to a second glance at that dejected tawny mop of
hair than to hear more of his self-indictment.

CHAPTER XVIII
THE HOUSE DIVIDED

After parting from Bessie at her father's door, John spent twenty-four
hours in dumb agony at his hotel, devoting much time to uncounted
attempts to frame a letter to her. But the one which finally went by
the hands of a messenger was a mere cry that broke out of his
heart. All it brought back was an answering cry,—four pages with
impetuous words rioting over them. There were splotches of ink
where the pen had been urged too recklessly, and as John held it up
to the electric light, he tried to imagine there were watery stains
upon it.
That night Hampstead left Los Angeles for San Francisco and
spent an aimless Saturday brooding upon the ocean beach, needing
no sight of the jutting Cliff House rocks upon which his lips had first
touched Bessie's to embitter his reflections. Sunday morning,
however, as early as nine o'clock, found him threading the graveled
paths of the little park in Encina, and taking his place upon the rustic
bench across from the dingy chapel. The cleat remained on the door.
God was still nailed up!
John could not help thinking that he, too, was rather nailed up.
Drawing Bessie's last letter from his pocket, he held it very tenderly
for a time in his hand, then opened it to the final paragraph, which
his eyes read dimly through a mist that overspread his vision like a
curtain of fog.
"I shall always love you, John," her pen had sobbed, "—always;
or at least, it seems so now. But you have hurt me in what touches a
woman nearest. I have tried to understand—I think I have forgiven
—but that full confiding trust!—Oh, John!"
The letter didn't cut off hope exactly; but it didn't kindle any
bonfires, either. As John read it, he felt forlorn and helpless, and
perceived that he had made rather a mess of things generally.
And, in the meantime, there was absolutely nothing more
important for him to do than to sit on the park bench before this
wretched-looking, dishonored little church and watch to see whether
any children came to Sunday school.
Yes,—two were coming now. One was a little girl of six or
seven, in a smock immaculately white. She was bareheaded, but her
flaxen locks were bound with a bright blue ribbon that just matched
the blue of her eyes. Her stockings were white, and her shoes were
patent leather and very shiny. She walked with precise, proud steps,
and looked down occasionally at the glinting tips of her toes to make
sure that they were still unspotted. Once she stopped and touched
them daintily with the handkerchief she carried in her hand, and
then glanced up and around swiftly with a guilty look.
By her side walked little brother. He might have been four. He
might have been wearing his first pants; his feet might have been
uncomfortable; the elastic cord on his hat might have been pinching
his throat most irritatingly, and probably was; but for all of that he
trudged along sturdily, as careful of his four-year-old dignity as his
sister obviously was of her motherly office.
He stretched his legs, too, to take as long steps as she, which
was not so difficult, because his sister minced her gait a little.
Together they swung around the corner, and their feet pattered
on the board walk leading across the sod to the chapel. Involuntarily
they stopped a moment where Elder Burbeck had borrowed the
plank, then stepped over the hole and mounted with confident,
straining steps to the platform. The sister was now a little in
advance, one hand holding her brother's and lifting stoutly as he
struggled to surmount the unnatural height.
But the door of the church was closed. This nonplussed the little
lady for just a second, after which she thrust up her chubby hand
and gave the knob a turn. The door did not respond. She rattled the
knob protestingly, and then, looking higher, saw the plank nailed
across.
At this the small miss stepped back confounded, to the
accompaniment of childish murmurings. Little brother did not
understand. He clamored to be admitted to his "Sunny Kool." The
little woman tried again, but the door baffled her most indifferently.
However, after a moment of wondering dismay, this tiny edition of
the feminine retreated no farther than to turn and sit down upon the
steps, first dusting them carefully, and inducing little brother to sit
beside her. Strength had been baffled, but faith was still strong.
"The eternal woman!" commented John reverently. "So Mary
waited at the tomb."
But other children were coming, and soon a fringe of little
bodies was sitting around the platform, and soon a border of little
feet decorated the second step, the girls' feet neatly, daintily
composed; the boys' feet restless, clumsier, beating an insistent
tattoo as they awaited the appearance of some grown-up who could
admit them or explain.
"Teacher! Teacher!"
One little girl set up the shout, and like a bevy the smaller
children swarmed across the street and into the park to meet a very
slender girl, perhaps sixteen years of age, with her light brown hair
in half a dozen long, rolling curls that, snared at the neck by a wide
ribbon, hung half way down her back.
Attended eagerly by this childish court, the babble of their
voices rising about her, the girl mounted the steps, stood a moment
in confusion before the locked and barred door, then looked about
her helplessly, almost as the children had done.
"This is my cue," John declared with decision, rising from his
seat and crossing to the chapel.
"My name's Hampstead," he began, taking off his hat to the girl.
"I belong to the First Church, Los Angeles."
"How do you do, Brother Hampstead," she responded, in a voice
that expressed instant confidence, while her large eyes, blue as the
sky, lighted with pleasure and relief. "I am Helen Plummer, teacher
of the infant class."
"You seem to be embarrassed," John proceeded.
"Whatever shall I do?" confessed the young lady, looking at the
barred door, at her charges about her, and at John.
John laid his hand upon the plank at the end where it projected
beyond the edge of the little, coop-like vestibule, and gave it a
tentative pull. It did not spring much. Burbeck's nails had been long,
and he had driven them deep. But John was strong. He swung his
weight upon the end of the plank and it gave a little. He swung
harder, and it yielded more. Presently he heard a squeaking,
protesting sound from the straining nails, and increased his efforts
till the veins knotted on his forehead.
"Bet y' he can't," speculated an urchin whose chubby toes were
frankly barefoot and energetically digging into the sod of the lawn.
"Bet yuh he will," instantly countered another, shifting his gum.
"Oh, I do hope you can!" sighed the fairy thing with the curls
down her back and the eyes like the sky.
That settled it for John. This plank was coming off.
Nevertheless, there was a pause while he mopped his brow and
considered. The result of these considerations was to fall back for
reinforcement on two cobbles of unequal size chosen from the
gutter, the larger of which he used as a hammer while the smaller
served as a wedge, till, with a final wrench, the plank came free.
But Elder Burbeck had locked the door.
"A hairpin?" queried John of the sky blue eyes.
"I have not come to hairpins yet," blushed the teacher of the
infant class.
John remembered the buttonhook on his key ring, and after a
few moments of vigorous attack with that humble instrument the
bolt shot accommodatingly to one side and the door swung open.
"Thank you so much!" exclaimed the blue eyes, though the red
lips of pliant sixteen said never a word, but framed themselves in a
very pretty smile.
John acknowledged the smile with one of his broadest. At the
same time, he reflected that Miss Helen's failure to regard as
seriously unusual either the barred door or its violent opening was
significant of the state to which affairs in the little church had come;
and it was with a grim sense of duty well performed that the big
man followed the trooping children into the chapel and looked about
him.
The building was small, yet somehow it appeared larger inside
than out. The utmost simplicity marked its furnishings. The seats
were divided by two aisles into a central block of sittings and two
side blocks. The pulpit was a mere elevated platform at one side,
flanked by lower platforms, one of which supported a cabinet organ.
The dull red carpet upon the floor was dreary looking; but the walls
and ceilings were neatly white, giving a suggestion of lightness and
cheer quite out of harmony with the circumstances under which
John had entered it.
The twenty or more children massed themselves, as if by habit,
upon the front seats, and presently, with Helen at the organ,
Hampstead had them singing lustily one song after another, while
the size of the audience increased by occasional stragglers until,
during the fourth song, two women appeared, each rather
breathless, and one with unmistakable evidences of having got
hurriedly into her clothes. John felt the eyes of the women upon him
suspiciously, and noticed that neither spoke to the other, and that
they took seats on opposite sides of the church.
At the end of the song, he walked over to the older of the two
ladies, who somehow had the look of a wife and mother in Israel,
and said:
"My name's Hampstead,—First Church, Los Angeles."
"I'm Sister Nelson," replied the lady, a trifle stiffly. "I teach a
class of boys. But I thought the church was closed till I heard the
organ. Are you a minister?"
"Me? No!" And John smiled at the thought, but he also smiled
engagingly. Mrs. Nelson instantly liked and accepted him and
allowed her stiffness to melt somewhat.
"I just happened in," John explained, as he turned to cross
toward the young lady on the other side, who appeared, he thought,
to eye him rather more suspiciously after such cordial exchange with
Mrs. Nelson.
"My name's Hampstead," he began. "First Church, Los Angeles.
I just happened in."
"I'm Miss Armstrong," replied the lady, with conviction, as if it
were something important to be Miss Armstrong. "I was teaching a
class of girls before Brother Aleshire left; or rather, was driven
away!" and the lady darted a look that ran across the little
auditorium like a silver wire straight at the uncompromising figure of
Sister Nelson. "I thought there wasn't to be any Sunday school until
I heard the organ."
"Guess I'm responsible for that," replied John. "I just kind of
butted in."
Miss Armstrong did not ask John if he were a minister. She knew
it was unnecessary after he said "butted in." But she also felt the
warmth of his engaging smile and yielded to it after a searching
moment, for he really did look like a well-meaning young man.
Before the pulpit, and in front of the central block of chairs
where the children were gathered, was a huge irregular patch in the
carpet. This patch was about mid-way between the two outer plots
of chair-backs, in the midst of one of which, like a solitary outpost,
sat the watchful Mrs. Nelson, while Miss Armstrong performed grim
sentinel duty in the other.
To this patch in the carpet, as to the security of neutral ground,
John returned after establishing his identity and status with the two
ladies, and from that safely aloof position, after a moment of
hesitancy, ventured to announce:
"Since we seem somewhat disorganized this morning, I suggest
that Sister Nelson take all the boys, and Sister Armstrong take all the
girls, while Miss Helen will take the little folks, as usual."
It was evident from their respective expressions that Mrs.
Nelson did not know about this idea, and that Miss Armstrong also
had her doubts; but the children settled it. The tots rushed for the
small platform on the left of the pulpit which had some kindergarten
paraphernalia upon it, while the larger boys charged for Sister
Nelson and began to arrange the loose chairs in a circle about her.
The larger girls made the same sort of an advance upon Miss
Armstrong.
Within five minutes, preliminaries were got out of the way,
heads were ducked toward a common center, and there rose in the
little church that low buzz of intense interest, possibly more
apparent than real, which an old-fashioned Sunday school gives off
at recitation period, and which is like no other sound in the world in
its capacity to suggest the peaceful, bee-like hum of industry and
contentment.
Standing meditatively in the center of the open space before the
pulpit, thrilling with pleasure at the situation, feeling somehow that
he had created it, John heard with apprehension a quick heavy step
in the little entry, saw the swinging inside doors give back, and
observed the stern, red face of Elder Burbeck confronting him across
the backs of the middle bank of chairs.
The Elder had a fighting set to his jaw; he had his undertaker
hat upon his head; and he glared at John accusingly as if he
instantly connected him with the policy of the open door. But as if to
make sure first just what mischief had resulted, Elder Burbeck's
glance swept the room, taking in by turns Miss Armstrong with her
girls, Sister Nelson with her boys, and Miss Helen with her
kindergarteners.
As the Elder gazed, his expression changed perceptibly, and he
reached up and took off his high hat, lowering it slowly, but
reverently.
John, who had been standing perfectly still upon the patch,
meek but unabashed, experienced an odd sensation as he witnessed
this manoeuvre. It was dramatic and as if some presence were in
the room which the Elder had not expected to find there. Yet,
notwithstanding this, the apostle of the status quo turned level,
accusing eyes upon John across the tiers of chairs, and began to
advance down the aisle upon the right where Sister Nelson had
seated herself. John, at the same moment, began a strategic
forward movement upon his own account, so that the two met
midway.
"You broke open the house of the Lord," charged Elder Burbeck
sternly.
"You nailed it up," rebutted John flatly, his features grave and
his whole face clothed in a kind of dignity that to Elder Burbeck was
as disconcerting as it was impressive.
"You nailed it up," rebutted John flatly.

The Elder opened his mouth to speak but closed it again


without doing so. Something in the very atmosphere was a rebuke
to him. Perhaps it was the presence of the Presence! He had indeed
nailed up the house of the Lord! He thought he had done a
righteous thing, but under this young man's eyes, burning with an
odd spiritual light, before his calm, strong face, and in the presence
of these children, the accusation smote the Elder deep. He began to
suspect that he had done a doubtful act.
"Keep back thy servant also from presumptuous sins," piped a
high voice sharply at his elbow, and Elder Burbeck started guiltily, as
if his conscience had shouted the sentiment aloud. It was only one
of Sister Nelson's boys singing out the text; nevertheless, the Elder
was as shaken as if he had heard a voice from on high.
But at this juncture John Hampstead put out his hand cordially.
Elder Burbeck took it—tentatively, almost grudgingly,—and was
again dismayed to feel how strong that hand was and to observe
how, without apparent effort, it shook him all over, as it had shaken
him that day upon the walk outside. Yet the Elder mustered once
more the spirit of protest.
"The church was closed by order of the District Evangelist," he
urged, but his urging, even to himself, sounded strangely lacking in
force.
"It was opened in the name of Him who said 'Suffer little
children to come unto me and forbid them not,'" replied the
interloper, quietly and emphatically, but not offensively.
In the meanwhile the subtle cordiality of John's manner did not
abate but seemed rather to grow, for, still clinging to the Elder's
hand, Hampstead walked with him back down the aisle to the open
space before the pulpit. Burbeck felt himself strangely subdued. He
was minded to rebel, to flame up; but somehow he couldn't. Yet
Sister Nelson's eye was upon him, and it would imperil his own
leadership to appear beaten by this mild-mannered young man who
assumed so much so coolly and executed his assumptions so
masterfully. The alternative strategy which suggested itself to the
mind of the Elder was to take the lead in showing that he recognized
the intrusion of Hampstead as somehow an intervention from which
good might come. To make this strategy effective, however, action
must be immediate; but the shrewd Elder was easily equal to that.
Sniffing the air critically for a moment, he announced, loudly enough
to be heard by all, even by Sister Nelson, busy with her boys:
"You need some windows open, Brother Hampstead! You go on
with your superintending; I'll attend to that myself."
Immediately the Elder laid his tall hat upon the pulpit steps and
busied himself with opening the windows at the top.
John watched him with carefully concealed amazement, until an
unmistakable awe settled in upon him; for here was obviously the
exhibition of a mystery,—the demonstration of a power within him
not his own. Here was something he had not done; yet which had
been done through him, through the presence of the Presence.
As the lesson hour proceeded, a trickling stream of adults began
to filter in. Their attitude, any more than Burbeck's had been, was
not that of people who enter a house of worship. Surprise,
excitement, conflict was written on their faces. They took seats in
one side section with Elder Burbeck and Miss Nelson, or upon the
other side with Miss Armstrong; and then, between fierce looks
across the abyss of chair-backs at the "disturbing element,"—the
other side in a church quarrel is always that,—they bent a curious
watchful eye on Hampstead.
At first the notes of the organ had notified those in the
immediate neighborhood that the house of God was no longer nailed
up. Members of each party, fearful that the other might gain an
advantage, began at once to spread the news in person and by
telephone, so that now all over Encina women were struggling with
hooks and eyes and curling irons, and men were abandoning Sunday
papers and slippers on shady porches, shaving, dressing, and
rushing in hot haste to the battle line.
When the children filed out, the opposing groups of adults
remained buzzing among themselves like angry hornets, but with no
more communication between the two ranks than bitter looks
afforded.
John, extremely desirous of getting well out of the zone of
hostilities, was actually afraid to leave these belligerent Christians
alone together. He thought they might break into pitched battle; the
women might pull hair, the men swing chairs upon each other's
heads. His fears were abruptly heightened by a series of violent
bumps on the steps outside, followed by a trundling sound in the
vestibule as if a cannon were being unlimbered. Instantly, too, every
face in the little chapel turned at the ominous sounds, but John was
puzzled to observe that the expression of even the bitterest was
softened at the prospect.
This was explained in part when there appeared through the
swinging inner doors not the muzzle of a fieldpiece, but a lady in a
wheel chair, who, though her dark hair had begun to silver, was
dressed in youthful white and had about her the air of one who
refused to allow mere invalidism to triumph over the stoutness of
her spirit.
Her vehicle was propelled by a solemn looking Japanese, and as
if by long understanding, one man slipped forward immediately from
each faction, and the two made a way among the chairs for the
Oriental to roll his charge to the exact center of the unoccupied
middle bank of sittings.
Bestowing on each helper a look of gratitude from her dark
eyes, which were large and luminous, the lady sent a benignant
smile before her round the church like one whose presence
sweetens all about it. Evidently she was one member of the
congregation who observed a scrupulous neutrality while holding the
affection and regard of all.
"The Angel of the Chair!" murmured Miss Plummer in John's ear,
as she passed to a seat with Miss Armstrong.
John looked again at the form in the chair, so frail and orchid-
like, with its delicately chiseled face and its expression of courageous
spirituality. Remembering how the features of all had softened at the
sound of the wheels, he felt that she well deserved the title. This
impression of her saintly character was somehow heightened by a
chain of large jet beads ending in a cross of the same material,
which the whiteness of the gown outlined sharply upon her breast;
so that John found himself instinctively leaning upon her as a
possible source of inspiration and relief.
From her position of carefully chosen neutrality, the Angel of the
Chair immediately beckoned Miss Armstrong to her from one side
and Elder Burbeck from the other. Each approached, without in any
way recognizing the presence of the other; and Miss Armstrong was
apparently asked to detail what had happened, Burbeck's part, it
would seem, being to amend if the narrative did his faction less than
justice.
The story finished, and the Elder nodding his assent to it, the
Angel of the Chair dismissed her informants and turned a welcoming
glance on John, who advanced with extended hand, but judging that
his formula of introduction was now unnecessary.
"I am Mrs. Burbeck," the lady said pleasantly in a rich contralto
voice.
Hampstead all but gasped. This delicate, spirituelle creature that
hard, red-faced partisan's wife! It seemed impossible.
But Mrs. Burbeck was composedly taking from her lap a twist of
tissue paper from which she unrolled a simple boutonniere,
consisting of one very large, very corrugated and very fragrant rose
geranium leaf, upon which a perfect white carnation had been laid.
"Do you know, Mr. Hampstead," she went on placidly, "what I
am going to do?" and then, as John looked his disclaimer, continued:
"I have always been allowed the privilege of bringing a flower for the
minister's button-hole. Brother Ingram would never take his flower
from any one else. When the rain kept me away, he would not wear
a flower at all. Brother Aleshire also took his flower from me."
"But," protested John, in sudden alarm, "I am not a minister at
all, you know. I just happened in, and I assure you that all I am
thinking of now is a way to happen out."
The Angel, it appeared, was a woman with deeps of calm
strength in her.
"You have been a real minister in what you have done this
morning," she said contentedly, entirely undisturbed by John's
embarrassed frankness.
"But how am I going to get out from under?" gasped the young
man, feeling more and more that he could trust this woman.
The Angel of the Chair smiled inspiringly.
"The Scripture has no rule for getting out from under," she
suggested quietly, "but there is something about not letting go of
the plow once you have grasped the handles."
The Angel was looking straight up at John now, searching his
eyes for a moment, then adding significantly:
"I do not think you are a quitting sort of person."
A quitting sort! John could have blessed this woman. In two
sentences she had felt her way to the principle he had tried to make
the very center of his character,—loyalty to duty and everlasting
persistence. Some people rather thought he was a quitting sort.
John knew he was not, and to prove it bent till his buttonhole was in
easy reach of the hands uplifted with the flower.
"And what," he asked, "does the minister do when he has
received this decoration from the Angel of the Chair?"
It was Mrs. Burbeck's turn to feel a flush of pleasure at this
appellation from a stranger.
"Why," she smiled, her large eyes lighting persuasively, "he goes
into the pulpit and announces a hymn."
"Which I am not going to do," declared John, "because I should
not know what to do next."
"In that hour it shall be given you," quoted the lady.
Now it was very strange, but when Mrs. Burbeck quoted this, it
did not seem like an appeal to faith at all, but the simple statement
of a fact. It chimed in, too, with that odd suggestion of the presence
of the Presence, which had come to John a while ago.
Welcome to our website – the ideal destination for book lovers and
knowledge seekers. With a mission to inspire endlessly, we offer a
vast collection of books, ranging from classic literary works to
specialized publications, self-development books, and children's
literature. Each book is a new journey of discovery, expanding
knowledge and enriching the soul of the reade

Our website is not just a platform for buying books, but a bridge
connecting readers to the timeless values of culture and wisdom. With
an elegant, user-friendly interface and an intelligent search system,
we are committed to providing a quick and convenient shopping
experience. Additionally, our special promotions and home delivery
services ensure that you save time and fully enjoy the joy of reading.

Let us accompany you on the journey of exploring knowledge and


personal growth!

ebookname.com

You might also like