Capstone: shop cart
| The spec | |
| Cart in session | |
| Checkout sketch | |
| Test totals |
The spec
Build a tiny shop: a product list, a cart that survives page reloads, a checkout that turns the cart into an order, and a totals test that guards the money math. Sessions hold the cart, the database holds the orders.
Products: list with an add button each Cart: quantities stored in the session Checkout: cart becomes one order row Totals: price times quantity, summed
Cart in session
The cart is a plain array in the session: product id maps to quantity. Adding an item reads the array, bumps the count, and writes it back. No tables, no migrations - the session is the whole storage layer for guests.
$cart = session()->get("cart", []); $cart[$id] = ($cart[$id] ?? 0) + 1; session()->put("cart", $cart);
Checkout sketch
Checkout freezes the cart into an order: re-read every price from the database, sum the lines, store one order row with the total, then clear the session cart. Prices always come from the server side, never from the form.
$total = 0; foreach ($cart as $id => $qty) { $product = Product::find($id); $total += $product->price * $qty; } $order = Order::create(["total" => $total]); session()->forget("cart"); echo $order->id;
Test totals
Money math deserves a test with known numbers: seed the session with two items of fixed price, visit the cart page, and assert the total on screen. If a discount rule ever breaks the sum, this test turns red first.
$this->withSession(["cart" => ["1" => 2]]); $response = $this->get("/cart"); $response->assertOk();
Next: Performance: kill N+1
Article author: Arthur Isaev