Capstone: A Complete, Working Flexible-Routing Site
Website Rebuild with Ruby on Rails
Chapter 12 · Capstone: A Complete, Working Flexible-Routing Site
Sam — the same site admin persona from every capstone in this series, reused a fourth and final time — logs into this course's own deployed Rails version. Every step below draws on a specific earlier chapter, closing with an attribution table, an honest scope note, and the close of the entire four-framework Website Rebuild series.
Sam opens the site. Phusion Passenger's Apache module is handling the request directly, embedded in the same Apache process that's always run this domain. RAILS_MASTER_KEY on the server decrypts config/credentials.yml.enc at boot.
At the login form, Sam enters the legacy admin credential. AdminUser#authenticate — from has_secure_password — verifies it against the stored bcrypt hash, functionally compatible across the $2a$/$2y$ version-tag difference for an ordinary password. A successful login quietly regenerates the hash under Ruby's own $2a$ tag.
Through the hand-built admin interface, Sam creates programming, then general-purpose-languages, then java, then fundamentals, then chapter-1 — five real levels deep. Each save triggers the before_save :compute_full_path callback from Chapter 2, recomputing that page's own path from its new parent.
Visiting the full five-segment path, Chapter 3's get '*path' glob route resolves it in one line, Chapter 4's layout and breadcrumb_for helper render the page with its ancestry, and Chapter 5's Propshaft-served dark theme applies with no build step involved.
Sam edits the Chapter 1 page's title. Chapter 8's update_title action and Strong Parameters handle the submission — but this time, Chapter 9's before_action :require_admin is in place, checking session[:admin_user_id] before the action runs at all. Logged out, the identical request would now redirect to the login page instead.
Sam decides fundamentals belongs under a different parent. Chapter 10's move_to updates fundamentals' own full_path first, then update_descendant_paths! recurses down and updates chapter-1's path too — the real payment of the cascade cost Chapter 2 deliberately deferred at the very start of the course.
Sam tries to delete java, which still has fundamentals beneath it. Chapter 2's dependent: :restrict_with_error refuses the operation, and Chapter 10's destroy action reads the resulting page.errors directly — no exception-handling code needed, the genuine ergonomic payoff of the same application-level design that was named as a real limitation back in Chapter 2.
Sam visits the kanji page. Chapter 7's resolution holds: Ruby's own character-aware String methods never risked corrupting the multi-byte character, and the database's utf8mb4 encoding — defaulted automatically by rails new --database=mysql since Rails 5.2 — stores it correctly with no manual configuration ever needed.
Sam checks the server log while loading the breadcrumb-heavy Chapter 1 page. Chapter 6's .includes() is doing its job — batched queries instead of one per tree level, the same fix every sibling course's own database chapter applied to the identical deliberately-planted problem.
Sam confirms assets:precompile's output is being served correctly, and that Passenger is spawning Rails processes cleanly under Apache — the last confirmation in a series that's now rebuilt the same real site four separate times.
Chapter Attribution
| Step | Chapter(s) Applied |
|---|---|
| 1. Visiting the deployment | 11 — Deployment |
| 2. Logging in | 9 — Admin Authentication |
| 3. Building the five-level chain | 2 — URL & Content Model, 10 — Admin CRUD |
| 4. Viewing the page | 3 — Routing, 4 — Views: ERB, 5 — Styling |
| 5. Editing the title | 8 — Dynamic Content & Forms, 9 — Admin Authentication |
| 6. Reorganizing | 2 — deferred cascade cost, 10 — move_to |
| 7. Delete refusal | 2 — dependent: :restrict_with_error, 10 — Admin CRUD |
| 8. Kanji migration | 7 — Rendering Content & the Kanji Edge Case |
| 9. N+1 sanity check | 6 — ActiveRecord ORM |
| 10. Deploy health check | 5 — Styling, 11 — Deployment |
Honest Scope Note
- No multi-admin roles or permission levels — a single legacy admin credential only
- No revision history or audit log of content edits
- No media/image upload handling
- No automated tests or CI pipeline
- No internationalization beyond the kanji character-storage edge case itself
- No rate limiting or lockout policy on the login form
credentials.yml.enc/master.key secrets philosophy (Chapter 11) — both real, checkable technical facts, not restatements of what Laravel already shared with Rails elsewhere in this course.
The Website Rebuild Series Is Now Complete
Four frameworks, one real site, rebuilt four separate times: Next.js, Django, Laravel, and now Ruby on Rails. Each course found its own genuine advantages and honest limits rather than declaring any single architecture simply "the best" — the same standard the Food Tracker Quartet set for comparative courses on this site.
Hands-On Exercises
Trace Step 6's reorganization through the code: what does move_to update first, and what does update_descendant_paths! update afterward?
Explain what changed between Step 5 in this capstone and the identical-looking action back in Chapter 8, and name the exact line of code responsible for the difference.
📄 View solutionName two genuinely Rails-specific findings from this course — not shared with Laravel or Django — and explain the real technical fact each one is grounded in.
📄 View solutionCourse Complete
- 12/12 chapters — Website Rebuild with Ruby on Rails is now complete
- Standout findings named honestly throughout — Ruby's open classes (Ch1),
includes()'s dynamic strategy (Ch6), reversed secrets philosophy (Ch11) - Real limits named honestly too — application-level (not database-level) delete protection (Ch2), Passenger as the honest minority choice (Ch11)
- Fourth and final course in the Website Rebuild series — alongside Next.js, Django, and Laravel
- The entire Website Rebuild series is now complete