Ruby on Rails Module 5
Hotwire: Turbo, Stimulus and real-time interview questions
Interview questions on “Hotwire: Turbo, Stimulus and real-time”: warm-ups, then what each harder question tests and how a good answer starts.
Warm-up questions
Short questions with short answers, each answered in full.
-
Fresher
In a new Rails 8.1 app, which edits turn the generated PWA scaffold on, and how do you confirm it works?
Make two changes. In config/routes.rb, remove the leading comment from the two PWA routes, so the router serves rails/pwa#manifest and rails/pwa#service_worker. In app/views/layouts/application.html.erb, change the manifest link from the ERB comment <%#= tag.link rel: "manifest" ... %> to real output with <%= ... %>, so every page points at the manifest. To confirm it, request the two URLs: /manifest.json should answer 200 application/json and parse as JSON with the app's name and display standalone, and /service-worker.js should answer 200 text/javascript. An integration test that asserts both statuses guards the switches against a later edit.
From the lesson PWA files and Hotwire Native
-
Fresher
A form in a Rails app submits with Turbo. What status should the controller return on a successful save, and what on a validation error, and why those two?
-
Fresher
What does respond_to with both format.turbo_stream and format.html give you that a stream-only action does not?
It serves two kinds of client from one action. Turbo adds text/vnd.turbo-stream.html to the Accept header of a non-GET form submission, so format.turbo_stream answers Turbo clients with a surgical stream response, status 200. Every other client, a plain GET or link, a browser without JavaScript, or a fully native screen, never sends that header, so format.html answers them with the ordinary redirect, status 303 after a create. The feature therefore works before Turbo is loaded and gets faster once it is, the progressive-enhancement approach the handbook recommends. A stream-only action would leave those clients with a blank or broken response.
From the lesson Turbo Streams and model broadcasts
-
Fresher
What does a Stimulus controller need to update a total when a quantity field changes?
-
Fresher
When would you write a custom Action Cable channel instead of relying on Turbo Streams broadcasts?
Questions with model answers
What each question tests, the first step of a good answer and the follow-ups to expect.
-
Mid to senior
A coaching centre wants its Rails app on the iOS and Android app stores soon, but the team writes Ruby and JavaScript and has no Swift or Kotlin developer. How would you use Hotwire Native, and what, if anything, would you build natively?
- What it tests
- Choosing a mobile approach from the team's skills: what Hotwire Native reuses, where native code is unavoidable, and the cost of each native screen.
- First step
- List what the app already has as web screens and mark which, if any, need a native control or a platform API; map the rest to Hotwire Native's web-content layer, which reuses the existing server HTML with no per-platform code.
- Follow-ups
-
- Where would a bridge component help, and what does it still need in Swift or Kotlin?
- A feature needs the device camera with a custom interface. Which layer, and what changes for releases?
- How do you ship a navigation change without waiting for app-store review?
From the lesson PWA files and Hotwire Native
Model answer, Pro. Model answers open with any pass; prices are in the notice on this page.Opening the model answers with your pass…
Model answers open with any MySmartCoPilot pass.
- Pro pass · 1 week₹79$2.99
- 30 days₹179$5.99
- 1 year₹1,699$45
One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.
Passes can’t be bought right now, so the model answers can’t be opened at the moment. If you have a pass, enter your licence key.
It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).
In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Mid to senior
You want new-student and edit forms to open as modals in your Hotwire Native app, and you want to change that later without an app-store release. Your Rails controllers run allow_browser versions: :modern. How do you set this up, and what could break?
- What it tests
- Setting up a path configuration you can change remotely, and spotting how a modern-only browser rule interacts with an app shell's web view.
- First step
- Write a path configuration with a rule whose patterns match the form URLs (for example /new$ and /edit$) and properties context modal, and serve it from Rails so it can change between releases.
- Follow-ups
-
- Why keep the file both bundled in the app and served from the server?
- How do you version the file so an older installed app keeps working?
- What might allow_browser versions: :modern do to the app's own web view, and how would you check?
From the lesson PWA files and Hotwire Native
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 4 minutes
-
Fresher to mid
An inline edit inside a Turbo Frame posts fine in the browser, but after a successful save the page does not update and after an invalid save the errors never show. The controller renders with status 200 both times. Explain what Turbo does with those responses and how you would fix the controller.
- What it tests
- Whether the candidate knows the statuses Turbo requires from non-GET requests and can connect each symptom to the wrong status code.
- First step
- Name what Turbo does with a 200 from a non-GET: it refuses to navigate to it and stays on the current URL. Then map each symptom to the status that would fix it, a 303 for the successful save and a 422 for the invalid one.
- Follow-ups
-
- Why does Turbo refuse to render a 200 from a POST or PATCH, specifically?
- Which Rails symbols produce the two statuses, and do the 8.1 scaffolds use them?
- What status would a server error return, and would Turbo render it?
From the lesson Turbo Drive and Turbo Frames
Model answer, Pro.In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 2 minutes
-
Mid to senior
You ship inline editing with Turbo Frames: a row becomes a form and returns on save. A screen-reader user reports they cannot tell when a row changed, and a keyboard user loses their place. What is happening, and how do you make the feature accessible?
- What it tests
- Whether the candidate knows a frame swap announces nothing and moves focus only to an autofocus element, and can name focus management plus a polite live region as the fix.
- First step
- State what a frame swap does for assistive technology: Turbo toggles aria-busy and honours autofocus, but announces nothing. From there, the fix is to manage focus and announce the change yourself.
- Follow-ups
-
- Where would you move focus after the row returns, and why there?
- What kind of live region would you use, and why polite rather than assertive?
- Does aria-busy on the frame solve any part of this?
From the lesson Turbo Drive and Turbo Frames
Model answer, Pro.In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Fresher to mid
A teacher marks a doubt answered from a list. One click should move the row to an "answered" list, drop the unanswered count and show a flash, and it must still work with JavaScript off. How do you build and verify this with Turbo Streams?
- What it tests
- Designing a multi-action Turbo Stream response, including a validation failure and an HTML fallback, and testing it without a browser.
- First step
- List the parts of the page that change (remove the row from one list, append it to another, update the count, show a flash) and write one turbo_stream action per part in the update template; keep a format.html redirect for clients without Turbo, and decide the status to return when the update fails.
- Follow-ups
-
- What status should a failed update return, and what should the stream do then?
- The same doubt is open on another teacher's screen. How do you keep both in step?
- How do you test the multi-action response and the fallback without a browser?
From the lesson Turbo Streams and model broadcasts
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 4 minutes
-
Mid to senior
Doubts in a batch must reach that batch's members in real time, never students from other batches. Using broadcasts_to and turbo_stream_from, how do you deliver the updates, stop an outsider from subscribing, and prove the boundary holds?
- What it tests
- Broadcasting to a stream and authorising who may subscribe beyond the signed name, and testing that another batch receives nothing.
- First step
- Note that turbo_stream_from signs the stream name but turbo-rails' default channel streams to any verified name, so decide where permission is enforced: render the subscription only for members, or write a custom channel whose subscription_allowed? checks membership on the server before it streams.
- Follow-ups
-
- Why is a signed stream name not enough to keep outsiders out on its own?
- Where should the permission check live, and why on the server rather than the view?
- How would you test that a doubt in another batch produces no broadcast on this batch's stream?
From the lesson Turbo Streams and model broadcasts
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 4 minutes
-
Fresher to mid
A Stimulus controller adds a resize listener to the window in connect() to adjust a chart when the viewport changes. After Turbo replaces the page section, the chart is gone but resize events still log messages to the console. What went wrong, and how do you fix it?
- What it tests
- Understanding of the Stimulus lifecycle under Turbo: connect() and disconnect() are called on each insertion and removal, and global listeners survive the element unless explicitly removed.
- First step
- When Turbo replaces the section, Stimulus calls disconnect() on the old controller. If disconnect() does not remove the resize listener, that listener keeps firing. Store a reference to the bound handler in connect() and call window.removeEventListener in disconnect().
- Follow-ups
-
- Why does Stimulus call disconnect() when Turbo removes an element?
- What other resources might need cleanup in disconnect()?
- How would you test that the listener is removed?
From the lesson Stimulus controllers
Model answer, Pro.In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 2 minutes
-
Mid to senior
A help page has 20 collapsible sections. The product manager wants them to open and close instantly, with ARIA state so screen readers announce the change. Would you use Turbo, Stimulus or CSS alone, and what accessibility requirements does each approach meet or miss?
- What it tests
- Choosing between Turbo, Stimulus and CSS for a disclosure pattern: latency, ARIA state management, and what each approach can or cannot do.
- First step
- CSS can toggle visibility with :target or a checkbox hack, but it cannot update aria-expanded. A Turbo Frame could load each panel from the server, but that puts a request behind every toggle. A Stimulus controller toggles the panel's hidden attribute and sets aria-expanded on the button, with no server round trip; check first whether the native details element is enough.
- Follow-ups
-
- How would you handle keyboard navigation between sections?
- What if the sections contain large images that should lazy-load?
- How would you test the ARIA attributes?
From the lesson Stimulus controllers
Model answer, Pro.In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Mid
A student enrolment form lets the user add up to three guardian contacts. Each row has name, phone and relation fields. How would you implement adding and removing rows with Stimulus, and what Rails pattern on the server accepts the nested data?
- What it tests
- Building a nested form with Stimulus: cloning a template, wiring remove buttons, and coordinating with accepts_nested_attributes_for and fields_for on the server.
- First step
- Put the row markup inside a template element. The Stimulus controller clones the template, updates the index in the field names, and appends it to the container. Each row has a remove button that calls a remove action, which sets a _destroy hidden field to "1" or removes the row entirely if it is new. On the server, accepts_nested_attributes_for :guardians, allow_destroy: true handles the nested params.
- Follow-ups
-
- How do you keep the field names unique across rows?
- What happens if JavaScript is disabled?
- How would you validate the maximum of three guardians?
From the lesson Stimulus controllers
Model answer, Pro.In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Fresher to mid
A WebSocket connection opens to
/cablebut the signed session cookie is missing. What shouldApplicationCable::Connection#connectdo, and what happens to any channel subscriptions?- What it tests
- Whether the candidate guards the socket in the connection with reject_unauthorized_connection and knows the socket is closed with a disconnect message before any channel subscribes.
- First step
- Name what the connection does with a missing or invalid cookie: call reject_unauthorized_connection, which sends a disconnect message (reason unauthorized, no reconnect) and closes the socket. From there, explain why no channel callback runs and what the browser does next.
- Follow-ups
-
- Why does authentication belong in the connection rather than in each channel?
- What does the client see, and can it reconnect without re-authenticating?
- How would you identify the user from a signed cookie safely?
From the lesson Action Cable and Solid Cable
Model answer, Pro.In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 2 minutes
-
Mid to senior
A Rails 8.1 app uses Solid Cable for Action Cable, expecting 5,000 concurrent subscribers at 100 messages per second. What signs show you need the Redis adapter, and what trade-offs does switching introduce?
- What it tests
- Whether the candidate names measurable signs (poll latency, database load, delivery delay) and the latency, persistence and operational trade-offs of Redis against Solid Cable.
- First step
- State how Solid Cable works: it polls the database about every 0.1 seconds. Then give measurable signs it is straining (poll latency nearing the interval, database CPU or I/O spikes, delivery delays) before weighing Redis.
- Follow-ups
-
- How does Redis pub/sub cut latency compared with polling?
- Does either adapter persist messages for a subscriber that was offline?
- What operational cost does running Redis add?
From the lesson Action Cable and Solid Cable
Model answer, Pro.In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 3 minutes
All Ruby on Rails interview questions · The Ruby on Rails track