Home · ELI5

Ruby on Rails

ActiveRecord Relations Explained

A relation holds a request for database records and can keep the records it fetches.

Illustrative library example · synchronous Rails 8.1.3 queries

1. Write a request

A relation is like a library slip asking for fiction books.

Request slipFiction booksRelationBooks still on shelf
What the slip represents
  • Book.where(category: "fiction") builds the query.
  • The relation can exist before any book records are fetched.

2. Add rules

You can ask for available books, sorted by title, with a limit of three.

Build the requestFiction · availableSort by titleAt most 3 books
The Rails query
  • Book.where(category: "fiction").where(available: true).order(:title).limit(3)
  • These calls build a relation without fetching its records.

3. Fetch the books

Calling to_a fetches matching records and gives you an array of book objects.

Requestto_aFetchBook objectsDatabase query → array
Other ways to request results
  • Iteration also loads records.
  • load loads records and returns the relation itself.
  • Calls such as count can ask the database for an answer without fetching book objects.

4. Keep the fetched books

The same loaded relation can reuse its fetched records when you read them again.

Same relationloaded?trueRecords in memory
When those books can be stale
  • loaded? reports whether the relation has loaded its records.
  • The database can change after that load; reload fetches again.
  • Adding query rules creates a derived relation that may need another fetch.

5. Count from the right place

On a loaded relation, size counts fetched records, while blockless count normally asks the database.

countAsk the databaseSQL countsizeCount fetched booksWhen loaded
Counting before a fetch
  • On an unloaded, plain relation, size calls a database count.
  • length loads the records before counting them.
  • The diagram simplifies ordinary ungrouped queries: query caching and known-empty queries can avoid a database round trip.