Dynamic Content & Forms

Website Rebuild with Ruby on Rails

Chapter 8 · Dynamic Content & Forms

Next.js answers this with an implicit Server Action. Django answers it with an explicit view function plus a separate ModelForm class. Laravel answers it with a Controller method plus a separate FormRequest class. Rails reaches a fourth, genuinely leaner shape: a single Controller action, with Strong Parameters written directly inline — no second class file at all.

The Route

# config/routes.rb patch '/admin/pages/:id/title', to: 'pages#update_title', as: :update_page_title

The Controller Action: Strong Parameters, Inline

# app/controllers/pages_controller.rb class PagesController < ApplicationController def update_title page = Page.find(params[:id]) page.update!(page_params) redirect_to page_path(page.full_path) end private def page_params params.require(:page).permit(:title) end end

params.require(:page).permit(:title) is Rails' own mass-assignment safety net — it raises if the expected :page key is missing, and returns a filtered hash containing only :title, silently dropping everything else. This is Strong Parameters, and there's no separate class involved at all: it's a private method on the Controller itself, by convention rather than framework requirement.

The leanest of the four structural answers
Django needed a whole separate ModelForm class. Laravel needed a whole separate FormRequest class. Rails needs neither — Strong Parameters lives as an ordinary private method on the same Controller class handling the request, the leanest structural shape of the four, not because Rails lacks the capability to separate concerns into classes elsewhere, but because this specific job doesn't call for one by Rails' own convention.

The Deliberate Gap — and Why It Looks Different Here

An absence, not a visible placeholder
update_title has no before_action :authenticate_admin! yet — deliberately, matching the same gap every sibling course left open in its own Chapter 8, to be closed in Chapter 9. But Rails' own version of this gap looks structurally different from Laravel's: Laravel's FormRequest has a dedicated authorize() method that currently returns a visible true. Rails' Strong Parameters has no equivalent authorization method at all — permit only ever answers "which fields are allowed," never "who is allowed to submit them." Rails' own idiom treats those as genuinely separate concerns, normally joined by an entirely separate before_action filter — which is exactly the line that's currently just missing, not present as a placeholder.

CSRF Protection

<%= form_with url: update_page_title_path(@page), method: :patch do |f| %> <%= f.text_field :title, value: @page.title %> <%= f.submit "Save" %> <% end %>

ApplicationController includes protect_from_forgery with: :exception by default, and Rails' own form_with helper automatically embeds a hidden authenticity_token field in every generated form — the combination is Rails' direct equivalent of Blade's @csrf and Django's {% csrf_token %}, requiring no manual token handling in the view at all.

Four Structural Answers, Compared

Next.jsDjangoLaravelRails
MechanismImplicit Server ActionView function + ModelFormController method + FormRequestController action + inline Strong Parameters
Separate validation class needed?No — but no built-in structure eitherYesYesNo
Auth/permission concernBundled into the action itselfA missing decoratorA visible authorize() placeholderA missing before_action filter

Hands-On Exercises

Exercise 1

Explain what params.require(:page).permit(:title) does, and explain why page_params lives as a private method directly on PagesController rather than in a separate class file the way Django's and Laravel's own equivalents do.

📄 View solution
Exercise 2

Explain what's currently missing from update_title, and explain why Rails' own version of this gap is structurally different from Laravel's authorize() { return true; } placeholder.

📄 View solution
Exercise 3

Explain the two mechanisms responsible for this chapter's CSRF protection, and how they work together without any manual token handling written in the view.

📄 View solution

Chapter 8 Quick Reference

  • params.require(:page).permit(:title) — Strong Parameters, Rails' own mass-assignment safety net
  • No separate validation class — the leanest of the four structural answers in this series
  • The gap looks different here — a missing before_action filter, not a visible placeholder method
  • protect_from_forgery + form_with — Rails' own automatic CSRF protection, no manual token handling
  • Next chapter: Admin Authentication