
Cover illustration: the CaseFlow browser is a conceptual application view. The companion lab supplies a Rails API source overlay, not a working web interface.
GitHub Copilot for Rails Engineers · Part 01
The first half-hour in a new repository should produce a defensible map, a list of unknowns, and one useful next action.
A client asks: “Can we add status transitions to this Rails API this week?” You have never seen the codebase. GitHub Copilot can help you explore it, but an answer that sounds like Rails is not evidence that this particular application behaves that way. Our goal is a small, falsifiable map of the current request path before proposing a change.
We will use CaseFlow, a synthetic Rails API source overlay. It is deliberately small enough to inspect and incomplete enough to expose an important habit: distinguish what source says, what a test asserts, and what a running system actually did. The companion materials contain the files, bounded prompt, answer guide, diagram source and evidence template.
Contents
- 0–5 minutes: predict before you inspect
- 5–15 minutes: follow the request through source
- 15–20 minutes: ask Copilot for a bounded map
- 20–27 minutes: turn assertions into observations
- 27–30 minutes: give the client one bounded answer
- Your 20–30 minute lab
- References and supporting materials
0–5 minutes: predict before you inspect {:#predict}
Write down your current hypothesis for POST /api/requests: what input is accepted, what gets saved and what comes back. Label every sentence prediction. This prevents your first impression or an AI suggestion from quietly turning into a fact.
The exercise is about one endpoint. Do not ask Copilot to explain the entire application yet. GitHub’s codebase exploration guide shows how repository and file context can narrow a question. Its review guidance is equally relevant: inspect the answer against actual files. Here, the hypothesis is an investigation aid, not a delivery promise.
5–15 minutes: follow the request through source {:#trace}
Start with caseflow-overlay/config/routes.rb:
namespace :api do
resources :requests, only: %i[index show create]
end
This declares a create route under /api. Rails routes dispatch incoming HTTP methods and paths to controller actions, as described in the Rails routing guide. The only: list matters: it does not declare an update route. Then inspect app/controllers/api/requests_controller.rb:
def create
request = ServiceRequest.new(request_params)
if request.save
render json: serialize(request), status: :created
else
render json: { errors: request.errors.full_messages }, status: :unprocessable_entity
end
end
def request_params
params.require(:request).permit(:title, :description)
end
The controller allows title and description from the request payload; status is not permitted there. Its private serialize method selects id, title, description, status, created_at and updated_at. There is no separate serializer file in this overlay. A reader who guesses “the serializer” from habit would be looking in the wrong place.
Next, the model constrains title presence, title length and status membership:
STATUSES = %w[open in_progress resolved].freeze
validates :title, presence: true, length: { maximum: 160 }
validates :status, inclusion: { in: STATUSES }
The migration declares a service_requests table with status defaulting to open. A migration describes a schema change applied during setup; it is not another method called for each POST. In a correctly migrated database, the default is a reasonable expectation for a new record created without an explicit status, but we still have to run the application before claiming to have observed it. See the Rails migration guide for the schema role of migrations.
The dotted link marks schema context, not an extra runtime step. The status labels describe the supplied controller branches; they are not a report of executed responses.
15–20 minutes: ask Copilot for a bounded map {:#ask}
Now use Copilot in VS Code with the relevant files in context. Ask for a map with citations rather than an implementation:
Trace POST /api/requests through the route, controller, model and migration.
Cite the exact file path for each source-backed statement.
Separate facts visible in source from behavior that still needs a run or test.
State what the supplied tests assert without claiming they passed.
List unknown behavior and do not edit files.
Check each path yourself. A citation is useful only if it points to a file that exists and supports that exact claim. Record a missing citation or a mistaken inference; correcting Copilot’s map is part of the exercise. In a client repository, keep sensitive data out of the prompt and follow the organization’s approved tooling rules.
20–27 minutes: turn assertions into observations {:#observe}
The included request spec has two cases: a valid title expecting a 201 response, an open status and one stored record; and a missing title expecting 422 with no record. Those are assertions in source, not reported pass results. The starter contains only an overlay, with no generated Rails application, lockfile or installed dependencies; we have not executed its specs in the authoring environment.
On a Mac with compatible Ruby, Rails and PostgreSQL installed, follow caseflow-overlay/README.md in the companion materials. Copy the overlay into a newly generated Rails API shell, inspect the diff, add a compatible rspec-rails, and record the actual output of:
bin/rails db:create db:migrate
bundle exec rspec spec/requests/api/requests_spec.rb
If setup fails, keep the first useful error. A blocker is evidence. Do not replace it with a hypothetical green test run. If it succeeds, send a synthetic HTTP request and capture the actual response before promoting the expected behavior to observed behavior.
| Statement | Evidence now | Classification |
|---|---|---|
Route includes create but no update
|
config/routes.rb |
Source fact |
Controller permits title, description
|
RequestsController#request_params |
Source fact |
Migration declares default open
|
Migration source | Schema fact; runtime effect pending |
Valid request returns 201 in this environment |
Spec assertion only | Unverified until execution |
Client can transition to resolved
|
No route/action or test supplied | Unsupported |
27–30 minutes: give the client one bounded answer {:#client}
The useful answer is not “Copilot says the endpoint works.” It is: “The source defines creation with title and description, title and status validations, and a schema default of open. The supplied specs cover valid creation and missing title, but I have not run them in this environment. I do not see an update route. The next safe step is to boot the overlay, record the focused spec result, then scope a status-transition contract and tests.”
That answer supports a short engagement: a visible finding, a named uncertainty and a testable next issue. It also gives a stakeholder a clear boundary between discovery and implementation.
Your 20–30 minute lab {:#lab}
- Make three predictions in a local
ENVIRONMENT.mdusing the template (caseflow-overlay/ENVIRONMENT.template.md). - Trace the five files in the lab checklist (
docs/labs/01-codebase-diagnosis.md), then compare Copilot’s cited map against source. - Attempt the focused spec; record the versions, command, actual outcome or first blocker.
- Explain why a model that lists
resolveddoes not prove a client can perform a status transition. Draft one bounded issue for that transition.
Retrieval question: What evidence would let you change “the source suggests 201” to “I observed 201,” and why does a passing spec not prove the entire API is production ready?
Next in the series: we will refine the context we give Copilot—repository guidance, instructions and tool boundaries—while keeping the same evidence discipline.
References and supporting materials {:#references}
-
Download the CaseFlow companion package: source overlay,
docs/labs/01-codebase-diagnosis.md,prompts/01-trace-request.md, Mermaid source, answer guide and validation status. The overlay is not a complete runnable app; its request specs remain unexecuted in this authoring environment. - GitHub Docs: Using GitHub Copilot to explore a codebase.
- GitHub Docs: Review AI-generated code.
- Rails Guides: Routing from the Outside In.
- Rails Guides: Active Record Migrations.