Recursivity
All projects
Private

Wardrobe

A clothing inventory that outgrew Airtable

LanguageRuby on Rails 8
UsersSingle user, sign-up disabled
PhotosActive Storage
StatusPrivate
  • 315 items, filtered by category, type, colour, season, and whether they are still in use.
    315 items, filtered by category, type, colour, season, and whether they are still in use.
  • An outfit proposed from things marked in use, favouring whatever you have seen least recently.
    An outfit proposed from things marked in use, favouring whatever you have seen least recently.

A Rails app for managing a clothing inventory, replacing an Airtable base that had outgrown the tool. Items carry photos, categories, and colours; the index offers a gallery and a list view; and /outfit proposes something to wear.

Two interface details worth the trouble

Infinite scroll that degrades. Items load 48 at a time and append as you scroll, but the sentinel at the bottom of the page is a real <a href="?page=N">. With JavaScript off it is ordinary next-page navigation rather than a dead end.

A search field that keeps its focus. The search form is rendered outside the frame it updates. Inside it, the field was destroyed and rebuilt on every keystroke — which on a phone dropped focus and closed the keyboard mid-word. It also replaces a single history entry as you type instead of stacking one per keystroke, so Back means “leave search” rather than “delete one letter”.

The outfit suggester is shaped by the actual data

Two facts from the real wardrobe drove the whole design, and both are the kind of thing you only learn by looking:

The random seed lives in the URL, so a suggestion is reproducible and shareable rather than a one-time roll you can never get back.

Throwing something out shouldn't delete history

A saved outfit's garment references are ON DELETE SET NULL, so getting rid of a sweater leaves a gap in the outfits that used it instead of destroying them. The outfit's kind — dress or separates — is stored rather than inferred, because once a garment is nulled you can no longer tell a dress outfit missing its dress from a separates outfit.

Outfits can also be built by hand, posting to the same controller with the same checks, and the pickers are driven by the very scopes the suggester draws on — so the builder offers exactly what a suggestion could have contained.