/blog/index.xml

AI Can Build Apps in Minutes but Great Software Still Takes Years

In his book, Same as Ever, finance author Morgan Housel makes the point that most progress is slow and incremental and follows the path of compounding returns over time. He uses an excellent example of heart disease. Deaths from heart disease have been reduced by 1-2% per year since the 1950s.. This has led to millions of lives saved. As he says, “equivalent to saving a major city’s population every year”. Heart Disease

Read More

I Still Prefer Monoliths, But Claude Changed the Math

Is Claude changing my mind about microservices?

Anyone who knows me as a Rails or Phoenix developer already knows my default answer: start with the monolith. I am firmly in the Monolith First camp, and that opinion comes from experience, not theory. I have the battle scars from being in the microservice trenches during microservice battles of 2013-2014: too many repos, too much orchestration, too much cross-service debugging, and entire days lost to problems that had nothing to do with the product.

Read More

Location Search Without Elasticsearch: Combining Tsvector and Postgis

Search Without Elasticsearch: Combining Tsvector and Postgis

Geo-Ranked Full-Text Search with PostgreSQL tsvector and PostGIS

When users search for a location by name, they expect results that are both textually relevant and geographically close. We built a search system that combines PostgreSQL’s full-text search with PostGIS distance ranking — no Elasticsearch required.

Search Table

Rather than querying our main locations table with all of it’s metadata (millions of rows, dozens of columns), we maintain a dedicated location_searches table optimized for this single purpose:

Read More

From Ruby to Python - Bundler and Poetry

From Ruby to Python - Bundler and Poetry

Ruby and Python are two popular programming languages known for their simplicity, readability, and extensive libraries. Both languages offer package managers to handle dependencies and streamline project development. In the Ruby ecosystem, we have Bundler, while in Python, I have come to rely on Poetry. Let’s look at these two tools, exploring their features, usage, and benefits.

Dependency Management

Bundler

Bundler, the Ruby dependency manager, uses a Gemfile to define project dependencies and their versions. Bundler resolves the dependencies and installs the required gems (libraries) into the project.

Poetry

Poetry, the Python dependency manager, employs a pyproject.toml file to define dependencies, versions, and other project metadata. Poetry resolves the dependencies and installs them into the virtual environment, which isolates the project from the system Python installation.

Read More

Postgres - Use temporary table to query from CSV

Postgres - Use temporary table to query from CSV

If you need to compare the contents of a large CSV file the to data in your existing database, you might want to take advantage of temporary tables. A temporary table exists only for the duration of the database session or transaction in which it is created. These tables can be useful for storing intermediate or temporary data that you need to compare to your live data but don’t want to persist in the database permanently.

Let’s look at an example:

CREATE TEMPORARY TABLE temp_uploaded_orders (
  order_id INT,
  store_id TEXT,
  settled BOOLEAN
);

Read More

Postgres Tricks - Convert jsonb string to hhmmss from seconds

Postgres Tricks - Convert jsonb string to hhmmss from seconds

We sometimes need to convert strings to dates to intervals and back to string in Postgres. One common set of queries I reach for is to convert “seconds” field into something that is readable by human. Most of us read times in the “hh::mm::ss” format and don’t like to do math in our head.

Here’s a simple query with to_char to convert seconds into this format:

 SELECT TO_CHAR('95 second'::interval, 'HH24:MI:SS')
 -- "00:01:35"

Read More

tobr - Generate a branch name form story title

If you are lazy like me and thinking of branch names is mentally taxing, it is time for a tool. I’ve been using this small ruby script for over 3 years to generate branch names. The script looks like this:

#!/usr/bin/env ruby
# Usage: tobr "Add customer phone Number"

text = ARGV.first || ""
puts text.gsub(" ","_").downcase

Read More