LARAVEL Case Studies & Practical Application 2 — Questions and Answers
Question 1: A SaaS app needs to send welcome emails, generate a PDF invoice, and notify a Slack channel after a user registers. Which Laravel feature best handles this as a single, clean unit?
- Queued event listeners on a RegisteredUser event (Correct answer)
- A single controller method calling each task sequentially
- A scheduled Artisan command that polls for new users
- A middleware that runs after the response is sent
Correct answer: Queued event listeners on a RegisteredUser event
Dispatching a RegisteredUser event with multiple queued listeners decouples each side-effect and processes them asynchronously.
Question 2: Your e-commerce site must apply a 10% discount for logged-in users and a 5% discount for guests. Where is the most maintainable place to centralize this pricing logic in Laravel?
- A dedicated PricingService class injected via the service container (Correct answer)
- Inline if/else blocks inside the Blade template
- A global helper function in helpers.php
- A database trigger on the orders table
Correct answer: A dedicated PricingService class injected via the service container
A PricingService encapsulates business rules, is easily testable, and can be swapped via interface binding.
Question 3: An API endpoint receives bulk product imports (up to 10,000 rows via CSV). The upload times out at 30 seconds. What is the correct Laravel approach?
- Queue a job that chunks and processes rows in the background, returning a job ID immediately (Correct answer)
- Increase PHP max_execution_time to 300 seconds in php.ini
- Use a scheduled command to re-import the CSV every minute
- Stream the CSV response back to the client line by line
Correct answer: Queue a job that chunks and processes rows in the background, returning a job ID immediately
Offloading to a queued job returns a fast HTTP response while background workers handle processing without timeout risk.
Question 4: A multi-tenant Laravel app stores each tenant's data in a separate database. How should you switch the database connection per request without modifying config files on disk?
- Resolve the DB manager and call DB::purge() then set config(['database.connections.tenant.database' => $db]) at runtime (Correct answer)
- Create a separate .env file per tenant and reload it each request
- Use separate Laravel installations for each tenant
- Store all tenants in one database and filter by a tenant_id column only
Correct answer: Resolve the DB manager and call DB::purge() then set config(['database.connections.tenant.database' => $db]) at runtime
Purging and reconfiguring the connection at runtime via config() allows dynamic database switching without disk writes.
Question 5: You need to expose a REST API where unauthenticated users can read resources but only authenticated users can write. Which middleware setup achieves this cleanly in a resource controller?
- Apply auth middleware only to store, update, and destroy methods using $this->middleware('auth')->only([...]) (Correct answer)
- Apply auth middleware to the entire controller and allow guests via a policy exception
- Remove all middleware and check Auth::check() manually in each method
- Use a global middleware that redirects all unauthenticated requests to login
Correct answer: Apply auth middleware only to store, update, and destroy methods using $this->middleware('auth')->only([...])
Scoping middleware to specific methods with only() lets index and show remain public while write actions require authentication.
Question 6: A Laravel job fails after 3 attempts due to an external API being unavailable. What should you configure to automatically retry the job with exponential back-off and eventually move it to a failed jobs table?
- Set $tries, $backoff, and implement failed() method on the job class (Correct answer)
- Wrap the job logic in a try/catch and re-dispatch the job from the catch block
- Use a Kernel schedule to retry failed jobs every minute
- Set QUEUE_RETRY=true in the .env file
Correct answer: Set $tries, $backoff, and implement failed() method on the job class
$tries controls max attempts, $backoff sets delay between retries, and failed() handles cleanup after all attempts are exhausted.
Question 7: Your Laravel application's N+1 query problem is causing 200+ queries on a page listing orders with customers and products. Which single Eloquent change fixes this?
- Eager load relationships with Order::with(['customer', 'products'])->get() (Correct answer)
- Add a raw JOIN query replacing all Eloquent calls
- Cache the entire orders table in Redis and query the cache
- Use DB::select() with a manually written LEFT JOIN
Correct answer: Eager load relationships with Order::with(['customer', 'products'])->get()
Eager loading with with() issues one query per relationship instead of one per model instance, eliminating the N+1 problem.
A SaaS app needs to send welcome emails, generate a PDF invoice, and notify a Slack channel after a user registers.
Which Laravel feature best handles this as a single, clean unit?