Reading Roundup: Embeddings in Ruby, domain models, and product thinking
The AI search rabbit hole, a hidden Rails macro, and the article I didn’t expect to enjoy
Hey there,
Two articles on building semantic search and RAG tooling in Ruby this week, which probably tells you something about where the community’s head is at right now. Alongside those: a deep dive on value objects with composed_of (one of those Rails features that’s been sitting there quietly for years), a tiny inflections tip that solves a specific annoyance, and a PostHog piece on what product managers actually do. Yes, I know. Bear with it.
Aggregating models into value objects with composed_of
Rails’ built-in composed_of macro maps a set of denormalized database columns (like separate red, green, blue, alpha fields) into a proper value object class, giving you equality checks, conversions, validations, and database querying, without a full model refactor.
Read more
Building a RAG Tool in Ruby 4: What Actually Happened
Robby Grossman walks through building Clarion, a minimal-dependency Ruby CLI that ingests Jira, Confluence, and GitHub data into a vector database to surface historical project context when analyzing tickets, with an MCP server integration that took under two hours to build.
Read more
Building Semantic Search with AI and Vector Embedding in Rails
A practical guide to adding semantic search to a Rails app using ruby_llm and PostgreSQL’s pgvector extension, covering document chunking with overlap, HNSW indexing for fast retrieval, and hybrid scoring that weights results 70% by semantic similarity and 30% by recency.
Read more
WTF does a product manager do? (and why engineers should care)
PostHog breaks down the three PM skills worth borrowing: gathering the right context, tracking success with feedback loops, and communicating towards action rather than just describing problems.
Declare Acronyms in Rails Inflections
One call to inflect.acronym in config/initializers/inflections.rb teaches ActiveSupport’s inflector to preserve casing for terms like API, CSV, and GraphQL, fixing the Api::UsersController annoyance across camelize, underscore, classify, and titleize.
Read more
Quick notes and actionables
composed_of is one of those Rails features nobody uses and everyone should know: it’s designed for the case where multiple database columns all belong to the same concept. The article uses color fields as the example, but think about address fields, money (amount + currency), or any time you have a cluster of columns that always get accessed together. The macro handles conversion, validation, equality, and WHERE clauses. One caveat from the docs worth noting: ActiveRecord won’t persist value objects changed outside the writer method, so work through the model, not the raw columns.
The Clarion RAG tool is worth reading for the architecture decisions, not just the AI parts: the choice to build a CLI rather than an HTTP server is deliberately low-commitment. No hosting, no VPNs, no “who owns this?” conversation six months in. The author frames this as an “internal tooling maturity ladder”: start with a script, evolve to a CLI, then a gem, then a server, only when you’ve proved the thing is worth the maintenance. The MCP integration is also worth a look. Once you have a CLI that does something useful, exposing it to Claude Code with the mcp gem apparently takes under two hours.
pgvector is probably the most practical starting point for vector search if you’re already on PostgreSQL: no new infrastructure, transactions work normally, and your embeddings sit in the same database as the rest of your data. The JetRockets article is thorough on the chunking strategy (1,000 characters, 200-character overlap to prevent context loss at boundaries) and the HNSW indexing setup. The 70/30 semantic/recency weighting is a sensible default, but it will need tuning depending on whether freshness matters for your particular data.
The PostHog PM article has a Duolingo example that’s worth reading slowly: the company was declining on daily active users. They tried referrals, premium trials, in-game mechanics. Nothing moved the needle. Then one data finding changed everything: current user retention rate was 5x more impactful than any other metric they were tracking. The entire roadmap shifted. That’s the context-gathering skill the article is describing in practice. The “communicate towards action” section is the most immediately useful bit for engineers. The difference between “we’re losing enterprise deals” and actually naming the five lost contracts, the three missing features, and which competing priority you’d drop to fix it.
Both the RAG and semantic search articles independently landed on the same embedding optimisation: generate the vector once, reuse it for multiple searches. In Clarion this cut from three sequential OpenAI embedding calls to one, with the three Pinecone queries then running concurrently. In the JetRockets article the same idea applies to chunking: send all chunks in one API call rather than one per chunk. Neither of these is a difficult change, but they’re easy to miss when you’re first getting something working and not yet watching your API request count.
The inflections tip is small but worth doing right now if you haven’t already: open config/initializers/inflections.rb and add inflect.acronym for every API, CSV, HTML, and PDF in your app. Worth checking for GraphQL too if you use it. Keep the list short though: every entry changes how camelize, titleize, humanize, and underscore behave across the whole app, so only add acronyms you’re actively using in class names, attributes, or view helpers.
Plenty to chew on this week. If you end up building something off the back of any of these, I want to hear about it. P.S. You can see everything I’ve been reading at dcyoung.dev/bookmarks.

