Building the-mcculloughs.org
The Problem
I want to own my family’s photo history. Not trust it to Flickr, Facebook, or any other platform that can change ownership, modify terms, or disappear entirely.
This is part of the same philosophy behind Jotter, my thoughts section, and this site itself: own your data. If the platform changes, your data should remain accessible. If the service shuts down, your memories should survive.
the-mcculloughs.org is an archive of my family photos spanning from the 1930s to the present day. It’s built with Rails 8, shares architectural patterns with Jotter, and prioritises mobile-first access and effortless uploading.
Why Leave Flickr?
I’ve been using Flickr for years. It’s a solid photo hosting service with good features and reasonable pricing. But there are problems:
Data Ownership
When you upload to Flickr, you’re trusting Yahoo (or SmugMug, or whoever owns it next) with your photos. The terms change. The ownership changes. In 2018, Verizon sold Flickr to SmugMug. Who knows what happens next?
My family photos from the 1930s - scanned negatives, precious memories - shouldn’t be subject to corporate acquisition strategies.
Platform Lock-In
Flickr’s organisation model doesn’t export cleanly. Albums, collections, tags, descriptions - they’re all structured around Flickr’s data model. Migrating elsewhere means rebuilding that organisation from scratch.
Storage Costs vs Control
Flickr Pro costs £60/year for unlimited storage. For a family archive that could span terabytes of high-resolution scans, that’s reasonable. But you’re paying for convenience, not ownership.
With self-hosting, storage is a one-time hardware cost (or cheap cloud storage), and you control retention, backups, and access indefinitely.
Family Sharing Limitations
Flickr’s sharing model is built for photographers sharing with audiences, not families sharing privately amongst themselves. Permissions are coarse-grained, organisation is photographer-centric, and the interface isn’t designed for casual family browsing.
Longevity
Will Flickr exist in 20 years? Maybe. Will it exist in 50 years when my nieces and nephews want to share these photos with their children? Unknown.
Self-hosted archives don’t depend on external companies or keeping up with whatever technology trends younger generations adopt. The data is portable, the code is open source, and the infrastructure is under my control.
What the-mcculloughs.org Is
A Rails 8 monolith for archiving and sharing family photos. It’s currently a photo sharing website, but I have bigger plans - family tree integration, timeline views, story annotations, collaborative family history. For now, it’s starting with the foundation: getting photos uploaded, organised, and accessible.
Current Features:
- Photo upload with metadata (date, location, people)
- Albums and galleries
- Polymorphic tagging (same pattern as Jotter)
- Public/private visibility controls
- Mobile-first responsive design
- Active Storage for file management
- Multiple image variants (thumbnail, medium, full-resolution)
Who It’s For:
Family members. My mum, my brother and sister, in-laws, cousins - anyone who wants to browse family history. Authentication is simple (no Facebook OAuth complexity), and the interface is designed for people who aren’t technical.
Shared Patterns with Jotter
the-mcculloughs.org and Jotter share significant architectural patterns:
Polymorphic Tagging
class Photo < ApplicationRecord
has_many :taggings, as: :taggable, dependent: :destroy
has_many :tags, through: :taggings
end
Tags work across photos, albums, and galleries. One tagging system, multiple content types. The same pattern Jotter uses for bookmarks and images.
Active Storage
Both applications use Rails’ Active Storage for file uploads:
class Photo < ApplicationRecord
has_one_attached :image
def thumbnail
image.variant(resize_to_limit: [200, 200])
end
def display
image.variant(resize_to_limit: [1200, 1200])
end
def full_resolution
image.variant(resize_to_limit: [3000, 3000])
end
end
Image variants are generated on demand and cached. Upload once, serve multiple sizes for different contexts (thumbnails in grids, full-resolution for viewing).
Rails Monolith Simplicity
Both are Rails monoliths. No microservices, no separate frontend/backend, no API layer. One codebase, one database, one deployment.
For applications serving a small number of users (family members, in this case), the monolith is the right choice. No distributed systems complexity, no service boundaries to manage, no network latency between components.
Public/Private Visibility
scope :public_photos, -> { where(is_public: true) }
scope :private_photos, -> { where(is_public: false) }
Same pattern as Jotter. Some photos are public (shareable with extended family or friends), others are private (immediate family only). Enforced at the model level, checked in controllers.
Mobile-First is Paramount
Family members browse photos on their phones, not desktops. The interface is designed mobile-first:
- Touch-friendly controls (large tap targets, swipe gestures)
- Responsive images (serve appropriate sizes for device)
- Fast loading (lazy loading, progressive image loading)
- Offline-capable (service worker for previously-viewed photos)
Tailwind CSS 4 handles responsive design with utility classes. Hotwire (Turbo + Stimulus) provides interactivity without heavy JavaScript frameworks.
Example: Photo Upload from Mobile
// Stimulus controller for drag-and-drop or tap-to-upload
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["input", "preview"]
upload(event) {
const files = event.target.files
Array.from(files).forEach(file => {
// Show preview immediately
const reader = new FileReader()
reader.onload = (e) => {
this.showPreview(e.target.result)
}
reader.readAsDataURL(file)
})
}
showPreview(dataUrl) {
const img = document.createElement('img')
img.src = dataUrl
img.className = 'w-32 h-32 object-cover rounded'
this.previewTarget.appendChild(img)
}
}
Tap the upload button, select photos from your camera roll, see previews immediately, submit when ready. No complex multi-step process, no confusing UI.
Ease of Uploading is Paramount
The biggest barrier to a family photo archive is friction during upload. If uploading is tedious, photos stay on phones and hard drives instead of being archived.
Batch Upload
Select multiple photos at once, upload in one operation. Active Storage handles multiple attachments, background jobs process image variants.
Metadata Auto-Detection
EXIF data is parsed automatically:
- Date taken (from camera metadata)
- GPS coordinates (if available)
- Camera model
- Orientation
Users can override or supplement this data, but defaults are extracted from the image itself.
Progressive Enhancement
The upload form works without JavaScript (standard file input + form submission). With JavaScript, it’s enhanced with drag-and-drop, previews, and progress indicators.
What’s Next
Photo sharing is the foundation, but I have bigger plans:
Family Tree Integration
Link photos to family members, show relationships, build a visual family tree with photos attached to nodes.
Timeline Views
Chronological timeline of family history - births, weddings, events - with photos illustrating each moment.
Story Annotations
Family members can add stories, context, and memories to photos. “This is my grandmother’s house in 1947” or “This was taken the day before Dad left for the war.”
Collaborative Family History
Multiple family members contributing photos, stories, and corrections. Not just an archive - a living family history that grows over time.
Family Video Archive
I’ve transferred family videos from VHS tapes (yes, I’m old enough to have those). The plan is to integrate video snippets into the archive alongside photos - christenings, birthdays, holidays from the 80s and 90s. Same ownership philosophy, same longevity concerns.
Offline Access
Service worker for offline browsing. Download albums to your phone, view them without internet, sync changes when back online.
Why a Rails Monolith?
I could have built this as a SPA with a separate API backend. I could have used microservices. I could have gone serverless.
But Rails is the right choice for this:
Simplicity
One codebase, one server, one deployment. No coordination between services, no API versioning, no distributed tracing complexity.
Developer Velocity
Rails conventions mean I’m writing application code, not infrastructure glue. Active Storage handles uploads, Active Record handles database queries, Hotwire handles interactivity.
Long-Term Maintenance
This is a family project I’ll maintain for decades. Simplicity matters more than architectural novelty. Rails has been around since 2004 and will be around in 2044.
Extensibility
When I add family tree features, timeline views, or story annotations, they’ll integrate naturally with the existing Rails app. No cross-service communication, no API contracts to maintain.
Own Your Data
the-mcculloughs.org is part of a broader philosophy:
- This site: Thoughts, notes, and writing live here, not on social media
- Jotter: Bookmarks and images under my control, not Delicious or Pinterest
- the-mcculloughs.org: Family photos owned by the family, not Flickr or Facebook
Platforms change ownership, modify terms, and shut down. Data you control survives.
Family photos from the 1930s deserve better than corporate terms of service.
Conclusion
the-mcculloughs.org is a Rails 8 monolith for archiving family photos. It shares patterns with Jotter (Active Storage, polymorphic tagging, public/private visibility), prioritises mobile-first access and easy uploading, and ensures family photo history isn’t subject to platform changes or corporate acquisitions.
It’s starting as a photo sharing website. It’ll grow into something more - family tree, timeline, collaborative history. But the foundation is: own your data, control your infrastructure, and ensure longevity.
You can view the source on GitHub. Yes, I know I misspelled my own name in the repository URL (mcculllughs vs mcculloughs). Renaming a GitHub repository causes redirect issues, breaks existing clones, and requires updating CI/CD configs. Too much hassle for a typo.