Ruby on Rails Module 3
Routing and controllers interview questions
Interview questions on routing and controllers: short warm-ups, then what each harder question tests, the first step of a good answer and its follow-ups.
Warm-up questions
Short questions with short answers, each answered in full.
-
Fresher
Why does params hold strings, and whose job is it to turn them into numbers and dates?
Answered in the lesson Controllers, params and strong parameters
-
Fresher
How do the session, cookies.signed and cookies.encrypted differ in a Rails 8.1 app?
-
Fresher
How does a controller filter stop a request, and what still runs after it has?
-
Fresher
resources :batches declares routes for seven actions. Name them, with the verb and path each answers.
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 Rails 8.1 JSON endpoint books seats. Its error tracker fills with NoMethodError from the filter line whenever a client sends the wrong shape, and the clients see 500. Make those requests report themselves correctly, and say what each failure should answer.
- What it tests
- Which filter catches a wrong shape, the status for each kind of bad input, the body an API should return, and how to change a live endpoint without breaking its clients.
- First step
- Read the filter line. A NoMethodError on the shape means require was called on something that is not a hash, so the shape is never checked. Write down the failures separately: wrong shape, missing key, unknown key, and values a model rejects. Each has its own status.
- Follow-ups
-
- What should the response body carry, and what must it never carry?
- When does expect! fit better than expect?
- How do you release this without breaking a client that is already sending the old shape?
- How would you keep the tracker useful once the 500s are gone?
From the lesson Controllers, params and strong parameters
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 4 minutes
-
Mid to senior
In a coaching-centre app, teachers edit a batch's name and timings while owners also set its fee and whether it takes bookings. Both edits post the same model. Design the parameter filtering, and say how you would prove a teacher cannot change the fee.
- What it tests
- Filtering that depends on the current role, where that decision belongs, the difference between filtering and authorisation, and the tests that prove it.
- First step
- List the keys each role may send, and notice that they differ. A filter method that takes the role, or one method per role, is the shape to reach for, with the role coming from the signed-in user rather than from the request.
- Follow-ups
-
- Why is a hidden field or a disabled input no protection at all?
- Where does authorisation sit beside this, and what does each layer catch?
- What happens if a teacher's form posts the fee anyway, and how would you learn about it?
- How would you test both roles without duplicating the whole test?
From the lesson Controllers, params and strong parameters
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 4 minutes
-
Senior to staff
One bookings controller serves a server-rendered page, a Turbo Frame on the batch page and a mobile client. The team wants to keep it as one controller. Decide how formats, statuses and error bodies should work, and when you would split it in two.
- What it tests
- Format negotiation, statuses a browser and a client each need, consistent error bodies, and the point at which a separate API controller is cheaper than one shared action.
- First step
- Separate what differs by client from what does not. The filtering and the model calls are the same; the rendering, the statuses and the error bodies differ. Sketch the action as one body of work with a respond_to block, then ask which parts are already diverging.
- Follow-ups
-
- Which statuses must stay the same for every client, and which may differ?
- How do you keep error bodies consistent across formats?
- What breaks for the mobile client when the page's redirect targets change?
- What would make you move the mobile client to its own namespace?
From the lesson Controllers, params and strong parameters
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 5 minutes
-
Mid to senior
Kaksha must sign a teacher out of every device at once, and a review flags that session data can be replayed from a copied cookie. Would you keep the default cookie store or move the session server-side? Defend the choice.
- What it tests
- Choosing a session store from requirements: what the cookie store cannot do (server-side invalidation, size), what a cache or database store adds, and what each costs.
- First step
- List what the requirement needs that a cookie store lacks: a server-side record the app can destroy, so a copied cookie stops working, and no 4 KB ceiling. Then weigh the cache store (fast, can vanish) against a database-backed store or the generated sessions table (durable, one query per request).
- Follow-ups
-
- Why can the default cookie store not sign a teacher out of every device?
- The generated authentication already uses a sessions table. Does that change the answer?
- What does a cache store give up that a database store keeps?
- How would you measure the cost of the extra lookup per request before committing?
From the lesson Sessions, cookies, flash and Current
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 4 minutes
-
Mid to senior
On the generated authentication, add idle and absolute session timeouts and a "log out of all devices" button. What do you change, and what timeout values do you pick for a coaching app that handles fee payments?
- What it tests
- Session expiry on the generated sessions table: idle and absolute timeouts enforced server-side, revoking every session of a user, and sensible values with their reasons.
- First step
- Decide where each timeout is checked. Idle and absolute limits belong in resume_session, against the row's updated_at and created_at, so the server decides, not the cookie. "Log out of all devices" is Current.user.sessions.destroy_all. Then pick values and justify them.
- Follow-ups
-
- Why enforce the timeout against the sessions row rather than the cookie's expiry?
- What idle and absolute values fit an app that handles fee payments, and why?
- After "log out of all devices", why does every old session_id cookie stop working?
- How does a renewal timeout differ from idle and absolute, and when is it worth adding?
From the lesson Sessions, cookies, flash and Current
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 4 minutes
-
Senior to staff
Kaksha moves from kaksha.example to a marketing site at www.kaksha.example and an app at app.kaksha.example, and sign-in must be shared across both. How do you scope the session and session_id cookies, and what are the risks?
- What it tests
- Cookie scope across subdomains: the Domain attribute and domain :all, the __Host- prefix trade-off, and the wider attack surface a shared cookie creates.
- First step
- Decide the Domain. A cookie with no Domain goes only to the exact host that set it, so sharing across subdomains needs Domain set to the parent, kaksha.example, through the session store's domain: :all (or an explicit domain). Then weigh what that widens.
- Follow-ups
-
- Why does the default, no Domain attribute, stop app.kaksha.example from reading a cookie set by www?
- What does the __Host- prefix guarantee, and why can a subdomain-shared cookie not use it?
- Which subdomains can now read or set the shared cookie, and why is that a risk?
- How does SameSite=Lax interact with requests between the two subdomains?
From the lesson Sessions, cookies, flash and Current
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 4 minutes
-
Mid to senior
Sign-in attempts are never refused in production, although the controller declares a limit of ten in three minutes and a test proves it with a memory store. The app runs on four servers behind one balancer. How do you find the cause, and what do you change so the limit holds for the whole deployment?
- What it tests
- Where a rate limit keeps its counts, what the store choice does across processes and servers, what the key should hold, and how the limit is watched once it works.
- First step
- Ask the running app which store the controller took at boot rather than reading the configuration files, and ask how many processes answer requests. One counter per process, or a store that keeps nothing, explains the symptom before any code changes.
- Follow-ups
-
- Each server counts on its own in a memory store. What limit does a client really get?
- Attempts arrive from many addresses for one account. What else can the key hold?
- How do you watch how often the limit fires, and what do you do with that number?
- An API client needs a 429 with a JSON body and a hint of when to retry. Where does that belong?
From the lesson Filters, errors and HTTP features
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 5 minutes
-
Fresher to senior
A controller carries a skip of :require_authentication with raise: false, added long ago when no filter had that name. Later the app's sign-in filter was renamed to require_authentication, and that page answered 200 to anyone for two weeks. How do you find every page in that state, and what stops a rename doing it again?
- What it tests
- Deny-by-default design for controller filters, what raise set to false costs, and a check that covers every controller rather than the ones someone remembered.
- First step
- List the places an exception can be written: every skip of the filter, every controller that does not inherit from the one that declares it, and every route that reaches a controller outside that tree. The list is the thing to test, not the filter.
- Follow-ups
-
- What does raise set to false buy, and when is it honest to use?
- Which test would have caught the rename on the day it was made?
- How do you keep the list of pages open to everyone easy to see in a code review?
From the lesson Filters, errors and HTTP features
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 5 minutes
-
Fresher to mid
In Kaksha, GET /reports/monthly reaches ReportsController#show with params[:id] = "monthly", and the page says no report was found. The routes file declares resources :reports and, below it, get "reports/monthly". Explain what happened, fix it two ways, and say which fix you would keep.
- What it tests
- Whether the candidate knows that the router takes the first route that fits, can read a routes table in order, and can choose between reordering and a constraint, then prove the fix with a test.
- First step
- Run bin/rails routes -g reports and read the rows from the top. Find the first row whose verb and path pattern accept GET /reports/monthly, and ask what value :id takes there.
- Follow-ups
-
- Which of the two fixes survives the next route someone adds?
- How do you prove the fix in a test without starting a server?
- What does GET /reports/june get once the constraint is in place?
From the lesson Routing: resources and RESTful URLs
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Fresher to mid
Kaksha's password-reset email builds its link with edit_password_path(token). Teachers report that the link in the email does not open the reset page, although the same helper works on the website. Explain the cause and the fix, and how every environment gets links to its own host.
- What it tests
- Path versus URL helpers, why a mailer has no request to take a host from, default_url_options per environment, and a mailer test or preview that shows the link before release.
- First step
- Open the email in the mailer preview and read the href of the link. Is it a full URL with a scheme and a host, or a path that starts with a slash?
- Follow-ups
-
- Why not take the host from the incoming request?
- How does a background job build the same link?
- How would a test have caught this before release?
From the lesson Routing: resources and RESTful URLs
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Mid to senior
Kaksha nests payments inside enrollments inside batches, and refunds inside payments, so the list of a payment's refunds needs batch_enrollment_payment_refunds_path(batch, enrollment, payment), and payments also carry accept, decline and reopen routes for refund requests. Propose a cleaner routes file and say how you would change it without breaking links already sent.
- What it tests
- Applying the one-level nesting rule, shallow routes, extracting a resource from repeated member actions, and moving URLs safely with redirects and routing tests.
- First step
- List the routes that really need a parent in the URL: those that list or create children. Every route that acts on one record by its own id can be shallow. Then look at the extra member actions and ask which noun they share.
- Follow-ups
-
- Which old URLs need redirects, and with which status?
- How does a controller find the parent once the URL no longer carries it?
- When is a deeper URL still the right choice?
From the lesson Routing: resources and RESTful URLs
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 4 minutes
All Ruby on Rails interview questions · The Ruby on Rails track