Reading about Rails concepts is one thing. Using them in a real app is where they finally click.
In this series we'll build Study Flow, a small app where you:
- create study plans and break them into topics,
- start and finish timed study sessions,
- get daily reminders and a weekly progress report by email,
- watch your dashboard update in real time.
Each post introduces one Rails concept (sometimes two small ones), and the app grows a little each time. By the end you'll have touched most of what makes Rails 8 special: the built-in authentication, Hotwire, Solid Queue, Solid Cable, Solid Cache, Active Storage, Action Text, and testing.
This series is for you if you're new to Rails or a junior developer. You should know basic Ruby (classes, methods, blocks). You don't need to know Rails.
What you'll learn in this post
- What a fresh Rails 8 app gives you out of the box
- How to generate the app and boot it
- What each important folder is for
- How a request travels through Rails (MVC)
What's new in Rails 8 (the short version)
Older Rails apps needed extra services before they felt "complete": Redis for jobs and live updates, a separate cache server, and a pile of JavaScript tooling. Rails 8 leans the other way: fewer moving parts, more built in.
Here's what a new app ships with:
| Piece | What it does | Used in part |
|---|---|---|
| Propshaft | Serves CSS, images and JS files | 1 |
| Importmap | Uses JavaScript modules without Node or a bundler | 5 |
| Turbo | Makes pages feel fast and live without writing much JS | 5, 8 |
| Solid Queue | Runs background jobs, stored in your database | 6 |
| Solid Cable | Powers real-time updates, stored in your database | 8 |
| Solid Cache | Caches data, stored in your database | 12 |
| Authentication generator | Generates login and sessions code | 2 |
The "Solid" trio means no Redis. Your database does the work. That's one less thing to install and run, which is a big win when you're learning.
Step 1: Prerequisites
You need:
- Ruby 3.2 or newer (the repo pins its version in
.ruby-version) - PostgreSQL installed and running
- Rails 8:
gem install rails
Check your versions:
ruby -v rails -v The second command should print Rails 8.x.
Step 2: Generate the app
rails new study_flow --database=postgresql --css=tailwind cd study_flow Two flags matter here:
-
--database=postgresqlbecause Rails 8 defaults to SQLite, but we'll use jsonb columns and a few Postgres features later. -
--css=tailwindto add Tailwind CSS for styling, so we don't spend the series writing CSS.
Don't skip the test setup. Rails generates a test/ folder by default, and we'll use it in every part.
Step 3: Boot it
bin/setup bin/dev bin/setup installs gems and creates your databases. bin/dev starts the web server and the Tailwind watcher together. It reads a file called Procfile.dev, which lists the processes to run.
Open http://localhost:3000 and you should see the Rails welcome page. 🎉
Step 4: A tour of the folders
Open the project in your editor. Here's the map, from most to least important for us:
app/ controllers/ # receive requests, decide what to do models/ # your data and business rules views/ # the HTML templates jobs/ # background work (part 6) mailers/ # emails (part 7) channels/ # real-time connections (part 8) javascript/ # JS loaded through importmap assets/ # CSS and images config/ routes.rb # which URL goes to which controller database.yml # database connections importmap.rb # JavaScript modules list queue.yml, cache.yml, cable.yml # the Solid trio's settings db/ migrate/ # step-by-step changes to your database schema.rb # the current shape of your database bin/ # helper commands: setup, dev, rails, ... test/ # your tests There are also a Dockerfile and a .kamal/ folder. Those are for deploying the app. We won't touch them in this series.
Two folders deserve a closer look.
db/ contains queue_schema.rb, cache_schema.rb and cable_schema.rb. These describe the tables Solid Queue, Solid Cache and Solid Cable use. You don't write them. They're part of the Rails 8 deal.
config/ holds the settings. For example, config/queue.yml configures how background jobs run, and we'll come back to it in part 6.
Step 5: How a request travels through Rails
Rails follows the MVC pattern. Think of a restaurant:
- Route: the host at the door. It reads what you asked for and sends you to the right waiter.
- Controller: the waiter. It takes your order, talks to the kitchen, and brings the result.
- Model: the kitchen. It knows the ingredients (your data) and the recipes (your rules).
- View: the plate. It's how the result looks when it arrives.
Your new app already contains a tiny example. Open config/routes.rb:
Rails.application.routes.draw do # Reveal health status on /up that returns 200 if the app boots with no exceptions, # otherwise 500. get "up" => "rails/health#show", as: :rails_health_check end Read the get line aloud: when someone sends a GET request to /up, hand it to the show action of the rails/health controller, and name this route rails_health_check.
Visit http://localhost:3000/up. You'll see a green page. That's a controller and a route working together, and it's the same path every request in Study Flow will take.
In the next parts we'll replace the welcome page with our own pages, starting with root "dashboard#show".
✅ How to test this
First, a manual check:
curl -i http://localhost:3000/up You should see HTTP/1.1 200 OK.
Now let's write our very first automated test. Create test/integration/health_check_test.rb:
require "test_helper" class HealthCheckTest < ActionDispatch::IntegrationTest test "the app boots and answers the health check" do get rails_health_check_path assert_response :success end end Run it:
bin/rails test You should see 1 runs, 1 assertions, 0 failures. We use rails_health_check_path, the route name from routes.rb, instead of typing "/up". Rails builds a _path helper for every named route, and you'll use these everywhere.
Common mistakes
-
PG::ConnectionBadwhen runningbin/setup. PostgreSQL isn't running, or your user can't create databases. Start Postgres and try again. - Styles don't appear. You started
bin/rails serverinstead ofbin/dev. Onlybin/devruns the Tailwind watcher. - Wrong Ruby version. If Rails complains, check
ruby -vagainst.ruby-version.
Recap
- Rails 8 ships with a full stack: Propshaft, Importmap, Turbo, and the Solid trio for jobs, real-time updates, and caching.
-
bin/setupprepares the app andbin/devruns it. - A request goes route → controller → model → view.
- We wrote our first test.
Next up
In Part 2 we'll add signup and login using the authentication generator that comes with Rails 8, and learn how sessions and Current attributes work.
Questions or stuck somewhere? Leave a comment and I'll help.

