Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

Ruby on Rails  Module 1 – Rails foundations

The Rails command line, console and generators

Run bin/rails for the server, console, database and routes, generate and destroy code after a --pretend preview, and try data in the console sandbox.

  • Beginner
  • 10 minutes
  • Examples run with Ruby 4.0.7 and rails 8.1.4
  • By MySmartCoPilot
Free lesson, Pro answers: 10 minutes
Free: the whole lesson. With a pass: the model answers to its 2 interview questions.

What you will learn

  • Use bin/rails commands for the server, console, database, routes and tests
  • Generate and destroy models and scaffolds, previewing each with --pretend
  • Read the migration a generator writes, including the modifiers that add constraints
  • Explore data safely with bin/rails console --sandbox and run scripts with bin/rails runner

Before you start

What you’ll learn · Before you start

What you will learn

  • Use bin/rails commands for the server, console, database, routes and tests
  • Generate and destroy models and scaffolds, previewing each with --pretend
  • Read the migration a generator writes, including the modifiers that add constraints
  • Explore data safely with bin/rails console --sandbox and run scripts with bin/rails runner

Before you start

On this page

In a new Rails 8.1 app, bin/rails --help lists 96 commands and tasks below its common ones, and one generator command can write a migration, a model, a test and fixtures in a single run. Typed carelessly, that same command writes code you did not want into the project; typed with care, it saves an afternoon of boilerplate and gets every name right.

This lesson works in Kaksha from recorded sessions. You will pick out the commands you need every day, preview a generator before it writes anything, read the migration it writes, see what a scaffold writes from one line, and try changes in a console whose database work is undone when you leave.

bin/rails runs every task of the app

bin/rails is the app’s own command. It boots the app with its bundle of gems, then runs the command you name, so the same word works on every computer of the team. With no command it prints its help, most common commands first:

bin/rails --help in the Kaksha app Ruby · sessions/commands_session.rb
# bin/rails --help inside the Kaksha app, written to a file once (each bin/rails command boots the app, which takes a
# few seconds): the commands it names first, then a few of the tasks this lesson uses.
require_relative "session"

Session.run(<<~SH)
  cd ../kaksha
  bin/rails --help > help.txt
  head -15 help.txt
  grep -c '^[a-z]' help.txt
  grep -E '^(credentials:fetch|db:migrate|db:prepare|db:rollback|middleware|notes|routes|runner|stats) ' help.txt
SH

Output

$ cd ../kaksha
$ bin/rails --help > help.txt
$ head -15 help.txt
Usage:
  bin/rails COMMAND [options]

You must specify a command. The most common commands are:

  generate     Generate new code (short-cut alias: "g")
  console      Start the Rails console (short-cut alias: "c")
  server       Start the Rails server (short-cut alias: "s")
  test         Run tests except system tests (short-cut alias: "t")
  test:system  Run system tests
  dbconsole    Start a console for the database specified in config/database.yml
               (short-cut alias: "db")
  plugin new   Create a new Rails railtie or engine

All commands can be run with -h (or --help) for more information.
$ grep -c '^[a-z]' help.txt
96
$ grep -E '^(credentials:fetch|db:migrate|db:prepare|db:rollback|middleware|notes|routes|runner|stats) ' help.txt
credentials:fetch                  Fetch a value in the decrypted credentials
db:migrate                         Migrate the database (options: VERSION=x, ...
db:prepare                         Run setup if database does not exist, or r...
db:rollback                        Roll the schema back to the previous versi...
middleware                         Print out your Rack middleware stack
notes                              Show comments in your code annotated with ...
routes                             List all the defined routes
runner                             Run Ruby code in the context of your appli...
stats                              Report code statistics (KLOCs, etc) from t...

Recorded with ruby 4.0.7 (revision 229531a6cf) +PRISM [arm64-darwin23] on macOS 26 arm64. To run it yourself: ruby commands_session.rb

The first lines list the commands you use most, each with a short alias: generate (g), console (c), server (s), test (t) and dbconsole (db). Below them come the other commands and tasks, 96 lines of them in this app, from about to zeitwerk:check. The few of them this module uses most:

Task What it does
bin/rails db:migrate and db:rollback Run the migrations not yet applied, or undo the last one
bin/rails db:prepare Set the database up if it does not exist, otherwise migrate it (bin/setup runs it)
bin/rails routes List every route with its name, verb, path and action
bin/rails middleware Print the middleware stack, as lesson 1 did
bin/rails runner Run a line of Ruby, or a file, with the app loaded
bin/rails notes and stats List TODO, FIXME and OPTIMIZE comments; count lines of code
bin/rails credentials:fetch Print one value of the encrypted credentials, new in Rails 8.1 for Kamal’s secrets

Every command accepts -h, and generators list their options that way too. One kind of task is missing from the help: the Rake task: A named job written in Ruby in lib/tasks/ (or shipped by a gem) that bin/rails can run, such as db:migrate or a task of your own app. your own app defines in lib/tasks/. bin/rails -T lists every task that has a description, yours included, and bin/rails -T db only those whose name contains db.

Checkpoint

Check: The bin/rails commands

  1. Question 1 of 2 Which command does bin/rails c start?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: The Rails console

    The common commands have short aliases: g for generate, c for console, s for server, t for test and db for dbconsole, as bin/rails --help printed.

  2. Question 2 of 2 A teammate's clone has no development database yet; yours has one that is two migrations behind. Which single task suits both?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: bin/rails db:prepare

    db:prepare runs setup if the database does not exist, or runs the migrations otherwise, so one task covers a new clone and an old one.

Generators write the files a convention expects, and a preview shows them first

A generator: A bin/rails generate command that writes the files a Rails convention expects for one name, such as a model with its migration, test and fixtures. turns one name into every file that convention puts around it. For a model, that is a migration: A Ruby file in db/migrate/ that changes the database schema one step, named with the time it was made so that every database runs the steps in the same order. to create the table, the model class, a test and its fixture: Sample rows for a table, written in YAML under test/fixtures/, that Rails puts in the test database so that every test starts with them.. Before it writes anything, --pretend (or -p) runs the generator and only reports what it would do. Step through what the model generator wrote, file by file:

Interactive · step by step One generator command, four files Step through the model generator. Each step adds the file that the recorded run listed next.
One generator command, four files, step 6 of 6. Showing generate model Teacher, The migration, The model, The model test, The fixtures. In focus: generate model Teacher.generate model TeacherThe migrationdb/migrate/The modelapp/models/teacher.rbThe model testtest/models/The fixturestest/fixtures/teachers.yml

The drawing shows the whole scene; its 6 steps are listed below.

Every step as text
  1. The command is read. Teacher names the model; name:string! and email_address:string!:uniq name two columns. The ! makes a column NOT NULL, and :uniq adds a unique index.
  2. A migration for the table. Active Record writes a migration whose file name starts with the time it was made, so migrations run in the order they were written. It creates the teachers table.
  3. The model class. app/models/teacher.rb holds class Teacher < ApplicationRecord and nothing else. Its columns come from the table, so the class needs no list of them.
  4. A test for the model. The test_unit generator adds test/models/teacher_test.rb, an empty Minitest test case for the model.
  5. Fixtures for the tests. test/fixtures/teachers.yml holds two sample rows that every test starts with, both filled with the placeholder MyString, so the unique index needs a different address in each. All four files follow from the one name, Teacher.
  6. The same list, two other ways. With --pretend the generator prints this same list and writes nothing. bin/rails destroy model Teacher removes the same four files, as the recorded run shows.

The session previews a Teacher model, generates it for real, prints its migration, then removes it again with bin/rails destroy, which undoes a generator file for file:

generate --pretend, generate, then destroy Ruby · sessions/generate_session.rb
# A model generator previewed with --pretend, run for real, its migration printed, then undone with destroy.
# Migration file names start with the time they were made, so that part prints as "…".
require_relative "session"

Session.run(<<~SH, masks: [[/\d{14}_create/, "…_create"]])
  cd ../kaksha
  bin/rails generate model Teacher name:string! email_address:string!:uniq --pretend
  bin/rails generate model Teacher name:string! email_address:string!:uniq
  cat db/migrate/*_create_teachers.rb
  bin/rails destroy model Teacher
  ls app/models db/migrate
SH

Output

$ cd ../kaksha
$ bin/rails generate model Teacher name:string! email_address:string!:uniq --pretend
      invoke  active_record
      create    db/migrate/…_create_teachers.rb
      create    app/models/teacher.rb
      invoke    test_unit
      create      test/models/teacher_test.rb
      create      test/fixtures/teachers.yml
$ bin/rails generate model Teacher name:string! email_address:string!:uniq
      invoke  active_record
      create    db/migrate/…_create_teachers.rb
      create    app/models/teacher.rb
      invoke    test_unit
      create      test/models/teacher_test.rb
      create      test/fixtures/teachers.yml
$ cat db/migrate/*_create_teachers.rb
class CreateTeachers < ActiveRecord::Migration[8.1]
  def change
    create_table :teachers do |t|
      t.string :name, null: false
      t.string :email_address, null: false

      t.timestamps
    end
    add_index :teachers, :email_address, unique: true
  end
end
$ bin/rails destroy model Teacher
      invoke  active_record
      remove    db/migrate/…_create_teachers.rb
      remove    app/models/teacher.rb
      invoke    test_unit
      remove      test/models/teacher_test.rb
      remove      test/fixtures/teachers.yml
$ ls app/models db/migrate
app/models:
application_record.rb
concerns

db/migrate:

Recorded with ruby 4.0.7 (revision 229531a6cf) +PRISM [arm64-darwin23] on macOS 26 arm64. To run it yourself: ruby generate_session.rb

The preview and the real run printed the same four files, and destroy removed the same four. Migration file names start with the moment they were made, here printed as …, so that migrations always run in the order they were written; the class inside, CreateTeachers, is named after the file. ls at the end shows app/models back as it was and db/migrate empty.

Destroying after you migrated

bin/rails destroy deletes the migration file, not the table it created. Roll the migration back first with bin/rails db:rollback, then destroy, or the table stays in the database with no migration that explains it.

Checkpoint

Check: Generating, previewing and destroying

  1. Question 1 of 2 What did bin/rails generate model Teacher … --pretend change in the app?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: Nothing; it printed the files it would write

    --pretend (or -p) is a preview: the output lists the files, and the app is unchanged until you run the command again without it.

  2. Question 2 of 2 You generated a model, ran bin/rails db:migrate, and now want the model gone completely. In which order?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: bin/rails db:rollback first, then bin/rails destroy model

    Undo in the reverse order: roll back the migration that created the table, then remove the files.

Field types and modifiers become columns and constraints

Each field of a generator command is name:type:index, and the migration it writes shows exactly what each part became. From the Teacher run:

You typed The migration wrote What the database enforces
name:string! t.string :name, null: false No row without a name
email_address:string!:uniq t.string :email_address, null: false and add_index :teachers, :email_address, unique: true No row without an address, and no address twice
(always) t.timestamps created_at and updated_at, filled by Active Record

The ! suffix and :uniq are read by railties’ generated-attribute code, and Rails’ own authentication generator uses the same pair for users: email_address:string!:uniq. Without a type the field is a string; :index instead of :uniq adds an index that allows repeats; references adds a foreign key column, as later lessons show. One generated file clashes with the new index: the fixtures give both sample teachers the placeholder MyString in every string column, so the unique index refuses the second row as soon as a test loads them. Give each fixture its own address before you run the tests.

Put the rule in the database too

A validation in the model gives a friendly error message, but it runs only in Ruby. Methods such as update_column and insert_all skip it, and two connections that check the same address at the same moment can both pass a uniqueness validation. The NOT NULL column and the unique index hold for every write, so generate the constraint with the column, then add the validation.

Checkpoint

Check: Field types and modifiers

  1. Question 1 of 2 What did name:string! become in the Teacher migration?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: t.string :name, null: false

    railties reads a trailing ! as null: false, which the database enforces for every write.

  2. Question 2 of 2 Two requests sign up the same email address at the same moment. Which part of the generated Teacher table stops the second?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: The unique index that email_address:string!:uniq added

    A unique index is the rule that holds under concurrent requests; a validation adds a friendly message on top.

A scaffold writes a whole resource once, from the fields you name

A scaffold: A generator that writes a whole resource at once: model, migration, routes, a controller with seven actions, views and tests. generates a whole resource: the model and migration, a route line (resources :batches), a controller with seven actions, HTML views, JSON views and tests. The session generates one for batches, migrates, and then looks at what it made:

A scaffold for batches, and the lines its fields became Ruby · sessions/scaffold_session.rb
# A scaffold for batches, its migration run, its routes listed, and the lines of the controller and of the form that
# the three fields became. The migration's timestamp and durations print as "…".
require_relative "session"

Session.run(<<~SH, masks: [[/\d{14}_create/, "…_create"], [/== \d{14} /, "== … "], [/-> \d+\.\d+s/, "-> …s"]])
  cd ../kaksha
  bin/rails generate scaffold Batch name:string! starts_on:date fee_paise:integer
  bin/rails db:migrate
  bin/rails routes -c batches
  grep -n -E 'params.expect|unprocessable_content|see_other' app/controllers/batches_controller.rb
  grep -n -E 'form[.][a-z_]+_field' app/views/batches/_form.html.erb
SH

Output

$ cd ../kaksha
$ bin/rails generate scaffold Batch name:string! starts_on:date fee_paise:integer
      invoke  active_record
      create    db/migrate/…_create_batches.rb
      create    app/models/batch.rb
      invoke    test_unit
      create      test/models/batch_test.rb
      create      test/fixtures/batches.yml
      invoke  resource_route
       route    resources :batches
      invoke  scaffold_controller
      create    app/controllers/batches_controller.rb
      invoke    erb
      create      app/views/batches
      create      app/views/batches/index.html.erb
      create      app/views/batches/edit.html.erb
      create      app/views/batches/show.html.erb
      create      app/views/batches/new.html.erb
      create      app/views/batches/_form.html.erb
      create      app/views/batches/_batch.html.erb
      invoke    resource_route
      invoke    test_unit
      create      test/controllers/batches_controller_test.rb
      invoke    helper
      create      app/helpers/batches_helper.rb
      invoke      test_unit
      invoke    jbuilder
      create      app/views/batches/index.json.jbuilder
      create      app/views/batches/show.json.jbuilder
      create      app/views/batches/_batch.json.jbuilder
$ bin/rails db:migrate
== … CreateBatches: migrating ====================================
-- create_table(:batches)
   -> …s
== … CreateBatches: migrated (…s) ===========================

$ bin/rails routes -c batches
    Prefix Verb   URI Pattern                 Controller#Action
   batches GET    /batches(.:format)          batches#index
           POST   /batches(.:format)          batches#create
 new_batch GET    /batches/new(.:format)      batches#new
edit_batch GET    /batches/:id/edit(.:format) batches#edit
     batch GET    /batches/:id(.:format)      batches#show
           PATCH  /batches/:id(.:format)      batches#update
           PUT    /batches/:id(.:format)      batches#update
           DELETE /batches/:id(.:format)      batches#destroy
$ grep -n -E 'params.expect|unprocessable_content|see_other' app/controllers/batches_controller.rb
31:        format.html { render :new, status: :unprocessable_content }
32:        format.json { render json: @batch.errors, status: :unprocessable_content }
41:        format.html { redirect_to @batch, notice: "Batch was successfully updated.", status: :see_other }
44:        format.html { render :edit, status: :unprocessable_content }
45:        format.json { render json: @batch.errors, status: :unprocessable_content }
55:      format.html { redirect_to batches_path, notice: "Batch was successfully destroyed.", status: :see_other }
63:      @batch = Batch.find(params.expect(:id))
68:      params.expect(batch: [ :name, :starts_on, :fee_paise ])
$ grep -n -E 'form[.][a-z_]+_field' app/views/batches/_form.html.erb
16:    <%= form.text_field :name %>
21:    <%= form.date_field :starts_on %>
26:    <%= form.number_field :fee_paise %>

Recorded with ruby 4.0.7 (revision 229531a6cf) +PRISM [arm64-darwin23] on macOS 26 arm64. To run it yourself: ruby scaffold_session.rb

bin/rails routes -c batches lists the eight routes of the seven actions (update answers both PATCH and PUT), with the names of their path helpers, such as batches and edit_batch. The controller already follows Rails 8.1 practice: it reads input with params.expect(batch: [ :name, :starts_on, :fee_paise ]), answers a failed save with :unprocessable_content, and redirects with :see_other after an update or a destroy.

The last command shows the form: one field for each attribute you typed, its kind taken from the column type, so the string gets a text_field, the date a date_field and the integer a number_field. Line 68 of the controller permits the same three names. Both were written once, from that one command line. A column you add later with a migration, say a capacity for each batch, appears in neither the form nor the permitted list until you add it to both by hand.

Checkpoint

Check: What a scaffold writes, and when

  1. Question 1 of 2 How many routes did bin/rails routes -c batches list for the scaffold's resources :batches line?

    Type a number.

    Show the answer: Question 1 of 2

    Answer: 8 routes

    Seven actions, index, create, new, edit, show, update and destroy, and update answers both PATCH and PUT, so the listing has eight routes.

  2. Question 2 of 2 Weeks after the scaffold, a migration adds capacity:integer to batches and you add a capacity field to _form. Saving a batch now keeps every field but the capacity. What is missing?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: capacity in the permitted list of batch_params

    The generator wrote the form and batch_params once, from the command line. A column added later reaches the model only when you add it to the form and to the params.expect list on line 68.

The console sandbox undoes its database changes when you exit

bin/rails console is an interactive Ruby prompt with the app loaded: models, helpers and the database. With --sandbox, every database connection the console takes starts inside a transaction that is never committed, so when you exit, the database discards every insert, update and delete you made. Step through the recorded session, and the SQL its log recorded:

Interactive · message by message A batch created in the sandbox, then gone Step through the recorded session. Arrows are what you type and the SQL the console sends to the database.
A batch created in the sandbox, then gone, step 6 of 6. Messages so far: Rails console to The database: BEGIN TRANSACTION; You to Rails console: Batch.create!; Rails console to The database: INSERT INTO batches; You to Rails console: Batch.count; You to Rails console: exit.Youtyping in the consoleRails consoleclosedThe database0 rowsBEGIN TRANSACTIONBatch.create!INSERT INTO batchesBatch.countexit

The drawing shows the whole scene; its 6 steps are listed below.

Every step as text
  1. The sandbox opens. bin/rails console --sandbox boots the app, and every connection it takes starts inside a transaction. The log recorded it as BEGIN deferred TRANSACTION, ahead of the first statement.
  2. You create a batch. Batch.create! runs an INSERT. Inside the open transaction it is written, but not committed, so no other connection sees it yet.
  3. The INSERT. The console sends the INSERT for Class 10 Science, and persisted? answers true: the row exists inside the transaction.
  4. You count. Batch.count runs SELECT COUNT(*) in the same transaction and sees its own row, so it answers 1.
  5. You exit. You leave the console with its transaction still open. No COMMIT is ever sent, so the database discards the uncommitted INSERT.
  6. A second process counts. bin/rails runner starts a new process with its own connection. It runs the same count and prints 0: nothing the sandbox did is left.

The session generates a Batch model, migrates, and feeds two lines to a sandboxed console, then counts the batches again from a new process:

A batch in the console sandbox, and the count afterwards Ruby · sessions/console_session.rb
# A batch created in the console's sandbox, the transaction the sandbox wrapped it in (from the development log,
# emptied first so that only the console's lines are in it), and the count once the console has exited. The
# console's own copy of the SQL log goes to standard error, which 2>/dev/null drops so that only its answers show.
require_relative "session"

Session.run(<<~SH)
  cd ../kaksha
  bin/rails generate model Batch name:string! fee_paise:integer --quiet
  bin/rails db:migrate > /dev/null
  rm log/development.log
  printf '%s\\n' 'Batch.create!(name: "Class 10 Science", fee_paise: 1_500_000).persisted?' 'Batch.count' | bin/rails console --sandbox 2>/dev/null
  grep -E 'BEGIN|Batch (Create|Count)' log/development.log
  bin/rails runner 'puts Batch.count'
SH

Output

$ cd ../kaksha
$ bin/rails generate model Batch name:string! fee_paise:integer --quiet
$ bin/rails db:migrate > /dev/null
$ rm log/development.log
$ printf '%s\n' 'Batch.create!(name: "Class 10 Science", fee_paise: 1_500_000).persisted?' 'Batch.count' | bin/rails console --sandbox 2>/dev/null
Loading development environment in sandbox (Rails 8.1.4)
Any modifications you make will be rolled back on exit
Switch to inspect mode.
Batch.create!(name: "Class 10 Science", fee_paise: 1_500_000).persisted?
true
Batch.count
1

$ grep -E 'BEGIN|Batch (Create|Count)' log/development.log
  TRANSACTION (…ms)  BEGIN deferred TRANSACTION /*application='Kaksha'*/
  Batch Create (…ms)  INSERT INTO "batches" ("name", "fee_paise", "created_at", "updated_at") VALUES ('Class 10 Science', 1500000, '…', '…') RETURNING "id" /*application='Kaksha'*/
  Batch Count (…ms)  SELECT COUNT(*) FROM "batches" /*application='Kaksha'*/
$ bin/rails runner 'puts Batch.count'
0

Recorded with ruby 4.0.7 (revision 229531a6cf) +PRISM [arm64-darwin23] on macOS 26 arm64. To run it yourself: ruby console_session.rb

Inside the sandbox persisted? answered true and Batch.count answered 1, because the console reads its own uncommitted row. The log shows the BEGIN deferred TRANSACTION that the sandbox opened before the INSERT. After the console exited, bin/rails runner counted 0: the transaction was never committed, so the row is gone.

Expecting the sandbox to undo more than the database

The sandbox wraps database operations only. A line that sends an email, writes a file or calls another service has done its work before you exit, and the exit cannot take it back. Keep such calls out of a sandbox session, or point them at something harmless first.

Two more console habits: reload! loads the code you changed without restarting the console (objects you already hold keep their old class), and the app and helper objects let you try a route helper such as app.rails_health_check_path (the /up route every new app has) or a view helper such as helper.pluralize without opening a page.

Checkpoint

Check: The console sandbox

  1. One question In the sandbox, Batch.count answered 1. What did bin/rails runner print after the console exited, and why?

    Choose one answer.

    Show the answer: One question

    Answer: 0, because the sandbox never committed its transaction

    Every connection of the sandboxed console works inside a transaction that is never committed, so its rows are gone once it exits and a new process counts 0.

runner and Rake tasks run scripts with the app loaded

bin/rails runner 'puts Batch.count' boots the app, runs one line or a whole file (bin/rails runner script/batch_summary.rb) and exits, which suits a cron job or a one-off script. A task you will run again belongs in lib/tasks/ as a Rake task, with a name and a desc line that bin/rails -T lists, so the team can find it and read it like any other code.

You need Use
To look at data, or try an idea bin/rails console --sandbox
One script, run once, that may change data bin/rails runner with a file in the repository
A job you run again, by hand or from a schedule A Rake task in lib/tasks/, called with bin/rails
A change to the schema A migration, never a script

A Rake task that never loads the app

task :count_batches do puts Batch.count end stops with NameError: uninitialized constant Batch: bin/rails loads the task files, but not your models. Make the task depend on the environment task, task count_batches: :environment, and Rails boots the app before the block runs.

Checkpoint

Check: Scripts with runner and Rake tasks

  1. One question Every Monday morning the office prints the batches that start that week, and a schedule should run it. Where should that code live?

    Choose one answer.

    Show the answer: One question

    Answer: In a Rake task in lib/tasks with a desc, called with bin/rails

    Repeated work is a Rake task (or a scheduled job) in the repository; a one-off script goes through runner with a file; the console is for trying things by hand.

Practise: choose the right command

The questions below come from this lesson’s sessions: the help, the generator runs, the scaffold and the sandbox. Each answer is explained at once:

Practice that adapts to you

Practise this lesson

14 questions about 6 ideas of this lesson. Each answer is explained at once, and what you get right is kept in this browser.

  1. Question 1 of 14 Which command lists every route of an app with its path helper name?

    Choose one answer.

    Show the answer: Question 1 of 14

    Answer: bin/rails routes

    bin/rails routes, with -c to filter by controller or -g to grep, as the scaffold session did.

  2. Question 2 of 14 The commands session ran bin/rails --help once into a file and then read the file three times. Why?

    Choose one answer.

    Show the answer: Question 2 of 14

    Answer: Every bin/rails command boots the app, which takes seconds, while reading a file is instant

    bin/rails boots the app for every command; when you need its output several times, save it once.

  3. Question 3 of 14 A teammate added lib/tasks/reports.rake with desc "Print the week's batches" and a task named reports:week. Where do you see it listed with its description?

    Choose one answer.

    Show the answer: Question 3 of 14

    Answer: In bin/rails -T, or bin/rails -T reports for only the matching tasks

    bin/rails --help shows the framework's commands and tasks; bin/rails -T shows every task with a description, including the ones in your own lib/tasks.

  4. Question 4 of 14 Which files did bin/rails generate model Teacher write? Choose every one.

    Choose every answer that is right.

    Show the answer: Question 4 of 14

    Answer:

    • test/fixtures/teachers.yml
    • app/models/teacher.rb
    • A migration in db/migrate

    The model generator writes the migration, the model, a model test and fixtures; scaffolds add the controller, views and routes.

  5. Question 5 of 14 Why does every migration file name start with a timestamp?

    Choose one answer.

    Show the answer: Question 5 of 14

    Answer: So that migrations run in the order they were written, on every computer

    The leading number orders the migrations and identifies each one in the schema_migrations table.

  6. Question 6 of 14 Which field writes an index on city that allows the same city twice?

    Choose one answer.

    Show the answer: Question 6 of 14

    Answer: city:string:index

    name:type:index for a plain index, name:type:uniq for a unique one, and a trailing ! on the type for NOT NULL.

  7. Question 7 of 14 What type does the column get from the field nickname, with no type written?

    Choose one answer.

    Show the answer: Question 7 of 14

    Answer: string

    Without a type a generated attribute is a string; name:index is read as a string with an index.

  8. Question 8 of 14 How does the generated BatchesController read the form fields of a batch?

    Choose one answer.

    Show the answer: Question 8 of 14

    Answer: With params.expect(batch: [ :name, :starts_on, :fee_paise ])

    params.expect requires the batch key and permits only the named fields, and answers 400 when the shape is wrong.

  9. Question 9 of 14 A batch fails validation in create. What does the scaffold send back to the browser?

    Choose one answer.

    Show the answer: Question 9 of 14

    Answer: The new form again, with status unprocessable_content (422)

    Failed saves render the form with 422; successful ones redirect, with :see_other after an update or destroy.

  10. Question 10 of 14 You edited app/models/batch.rb while a console was open. How does the console pick up the change?

    Choose one answer.

    Show the answer: Question 10 of 14

    Answer: Run reload!, and fetch your objects again

    reload! makes the console load changed code; an object made before it is still an instance of the old class.

  11. Question 11 of 14 You want to see how a new query behaves on the development data without changing any row by mistake. What do you start?

    Choose one answer.

    Show the answer: Question 11 of 14

    Answer: bin/rails console --sandbox

    The sandbox is for exploring: read freely, and any database write disappears when you leave.

  12. Question 12 of 14 In a sandboxed console you create a batch, then save a list of batches to tmp/report.txt with File.write. What is left after you exit?

    Choose one answer.

    Show the answer: Question 12 of 14

    Answer: tmp/report.txt, but not the batch

    Only database changes are undone on exit; files, emails and calls to other services have already happened.

  13. Question 13 of 14 What does bin/rails runner 'puts Batch.count' do?

    Choose one answer.

    Show the answer: Question 13 of 14

    Answer: Boots the app, runs the line of Ruby with the models loaded, prints the count and exits

    runner is for scripts and one-off lines with the app loaded; its changes stay.

  14. Question 14 of 14 A teammate wants to add a column with a runner script that calls ActiveRecord::Base.connection.add_column. What do you suggest instead?

    Choose one answer.

    Show the answer: Question 14 of 14

    Answer: A migration, so the change is recorded, ordered and run on every database

    Change the schema with a migration; use runner and Rake tasks for data and jobs.

Interview questions

Warm-up: what does bin/rails generate model Teacher name:string! email_address:string!:uniq write, and what do the two modifiers do?

It writes four files: a migration in db/migrate/ that creates the teachers table, the model app/models/teacher.rb, a model test and a fixtures file. In the migration, string! becomes null: false, so the database refuses a teacher without a name or an address, and :uniq adds a unique index on email_address, so no address can appear twice. t.timestamps adds created_at and updated_at. Nothing reaches the database until you run bin/rails db:migrate, and bin/rails destroy model Teacher removes the same four files.

Two questions of this module’s bank build on this lesson: getting a scaffold ready for users, and running a one-off data fix in production.

Model answers open with any pass: ₹79 for 1 week ($2.99), one payment that never renews.

  1. Fresher to mid

    You scaffolded batches for Kaksha and every page works on your laptop. Before teachers and guardians use it, what do you change in the generated code, and in which order?

    Model answer, Pro. Model answers open with any pass; prices are in the notice on this page. First step and follow-ups

  2. Mid to senior

    An import stored 2,000 students' fees in rupees instead of paise, so every fee is 100 times too small. How do you fix the production data safely, and why not by typing in the production console?

    Model answer, Pro. First step and follow-ups

Flashcards · 6 cards

Recall it, then check

Say the answer to yourself before you look: recalling it is what makes it stick.

  1. Which command lists the Rake tasks your own app defines, beside the built-in ones?

    bin/rails -T. bin/rails --help shows the common commands and their aliases first.

  2. How do you preview the files a generator would write, and how do you remove them again?

    Add --pretend to print the list without writing anything. bin/rails destroy with the same arguments deletes the files; roll back its migration first if it already ran.

  3. In bin/rails generate model, what do the field modifiers string! and :uniq become?

    string! makes the column null: false, so the database refuses an empty value; :uniq adds a unique index. The migration's t.timestamps line adds created_at and updated_at.

  4. You add a column to a scaffolded model weeks later. Does its form show the new field?

    No. A scaffold writes its model, eight routes, controller and views a single time; a later column reaches the form and the permitted list of params.expect only when you add it by hand.

  5. What happens to the rows you create in bin/rails console --sandbox?

    They disappear when you leave, because the sandbox wraps the whole session in a transaction it never commits. Scripts run with runner or a Rake task keep their changes.

  6. Which files does bin/rails generate model Teacher write, and when does the database change?

    A migration under db/migrate, the model under app/models, a model test and a fixtures file. The database changes only when bin/rails db:migrate runs.

Key takeaways

  • bin/rails boots the app with its own bundle and runs a command; --help lists the common commands with their aliases and 96 more commands and tasks in a new app, and bin/rails -T also lists the tasks your app defines.
  • Generators write the files that convention expects from one name, --pretend shows the list first, and bin/rails destroy removes the same files, after a rollback if you already migrated.
  • Field modifiers become constraints: string! writes null: false, :uniq a unique index, and t.timestamps adds the two time columns.
  • A scaffold writes the model, eight routes, a controller that uses params.expect and the views in one run, once: a column added later reaches its form and its permitted list only when you add it by hand.
  • bin/rails console --sandbox never commits its transaction, so its database changes are gone after you exit, while runner and Rake tasks run scripts with the app loaded and keep their work.

Terms in this lesson

fixture
Sample rows for a table, written in YAML under test/fixtures/, that Rails puts in the test database so that every test starts with them.
generator
A bin/rails generate command that writes the files a Rails convention expects for one name, such as a model with its migration, test and fixtures.
migration
A Ruby file in db/migrate/ that changes the database schema one step, named with the time it was made so that every database runs the steps in the same order.
Rake task
A named job written in Ruby in lib/tasks/ (or shipped by a gem) that bin/rails can run, such as db:migrate or a task of your own app.
scaffold
A generator that writes a whole resource at once: model, migration, routes, a controller with seven actions, views and tests.

References

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.