Membership Filtering System
Extended a reusable Rails filtering hierarchy to surface current members with deterministic random logo rotations.
What happened?
Built on top of our FormFiltering parent class by introducing a MemberFilter form object and a CurrentMemberFilter child, allowing nuanced filtering rules while keeping inheritance intact. Added a deterministic randomizer so member logos shuffle per session yet stay stable across pagination.
Tech & Impact
- Ruby on Rails
- Form Objects
- PostgreSQL
Turned a brittle list into a robust browsing experience—users get current members only, filters remain composable, and the logo carousel feels fresh without breaking cache or pagination.

Filter hierarchy brought to life
Starting from our shared FormFiltering base, I introduced member-specific form objects to surface active partners while keeping the filtering API familiar for the rest of the team.
FormFiltering base
Inherited the shared FormFiltering module so the member filters plug into existing validation and query hooks.
Member filter form
Added a MemberFilter form object responsible for scoping queries to active membership states and exposing shared predicates.
Current member child
CurrentMemberFilter < MemberFilter encapsulates stricter logic (status window, paid-through date) while reusing parent behaviors.
Deterministic shuffle
Seeded a pseudo-random ordering using session tokens so logos shuffle per visit yet remain stable while paginating.
Why the deterministic shuffle mattered
Marketing wanted member logos to feel fresh while users paged through results. The trick: stay random per refresh yet stable inside each session.
Scoped relations
Used PostgreSQL scopes + Arel to compose filters without duplicating SQL.
Session salt
Derive a hash from the current session to seed the random ordering each time the page loads.
Pagination aware
Persisted the shuffle seed across pages so users see a consistent random order while browsing.
Pain points
Debugging deterministic randomness was gnarly—documented the strategy and added tests to prevent regressions.