Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
Active Record Queries  ›  Lesson

Basic Queries and Conditions

Conditions 15 minfind, find_by and where fetch records; where returns a lazy relation you can keep chaining, and conditions should use hashes or ? placeholders rather than string interpolation.

Basic Queries and Conditions

A controller needs "book 7", "the member with this email", "all available books over 300 pages". Each is a database query, and Active Record lets you write each one as a short Ruby expression. The skill is knowing which method to reach for and what it gives back when nothing matches.

The rule

find by id, find_by for one, where for many — and never interpolate.

Book.find(7)                         # one Book, or raises RecordNotFound
Book.find_by(title: "Dune")          # first match, or nil
Book.where(available: true)          # a relation: zero or more books
Method Returns When nothing matches
find(id) one record raises ActiveRecord::RecordNotFound (a 404 page)
find_by(...) one record nil
where(...) a relation (list) an empty relation

Conditions come in three styles:

Book.where(author: "Le Guin")                  # hash: equality
Book.where(author: ["Le Guin", "Pratchett"])   # hash with array: IN (...)
Book.where(pages: 300..500)                    # hash with range: BETWEEN
Book.where(pages: 301..)                       # endless range: pages >= 301
Book.where("pages > ?", 300)                   # string with a ? placeholder
Book.where.not(available: true)                # NOT
Book.where(available: false).or(Book.where(pages: ..100))

where does not hit the database straight away. It builds a relation, a query-in-progress, and you can keep chaining: Book.where(available: true).where("pages > ?", 300) becomes one SQL query with AND. The query runs only when you need the rows — when you loop, call to_a, first, count or pluck(:title).

Handy extras: Book.first, Book.last, Book.take, Book.exists?(title: "Dune"), Book.pluck(:title) (an array of titles, no model objects).

The shortcut

Read the task and ask "id, one, or many?" An id from the URL → find. One thing by another attribute → find_by. A list → where. Then check how user input enters the SQL: a hash or a ? placeholder, never #{}.

Search box on the books pageStep 1 of 4
  1. Many or one?

    A search returns a list, so where.

Drills

Answer fast — trust the rule.

quick drill

Book.find_by(title: "Missing") finds nothing. What do you get?

quick drill

Which query is safe from SQL injection?

quick drill

How many SQL queries run for Book.where(available: true).where("pages > ?", 300).to_a?

quick drill

Which condition finds books with 100 pages or fewer?

quick drill

What does Book.where(author: "Le Guin").pluck(:title) return?

Remember

  • find by id, find_by for one, where for many — and never interpolate.
  • Shortcut: id, one or many; then check how input enters the SQL.
  • Trap: where returns a relation, never nil, and runs only when you use it.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

Explainfind, find_by or where?

For each task, pick find, find_by or where and say what it returns when nothing matches: (1) show the book whose id is in the URL, (2) look up a member by email at sign-in, (3) list available books with more than 300 pages. Then explain why where("title = '#{params[:q]}'") is dangerous and how to fix it.