Re: Why Ruby on Rails Still Matters

In an article for Contraption comparing Ruby on Rails and Next.js, Philip I. Thomas writes:

The truth is that the new wave of Javascript web frameworks like Next.js has made it harder, not easier, to build web apps. These tools give developers more capabilities - dynamic data rendering and real-time interactions. But, the cost of this additional functionality is less abstraction.

He then makes a great point about what makes Next.js apps unstable:

Using cutting-edge frameworks introduces instability through frequent updates, new libraries, and unexpected issues. Next.js applications often rely on a multitude multiple third-party services like Vercel, Resend, and Temporal that introduce platform risk.

This problem has been exacerbated by developers themselves. I don’t like Vercel, Resend, Temporal, Prisma, or any of the SaaS platforms whose business model seemingly relies on abstracting obfuscating away control of an application by selling their services to new and impressionable developers who hear about them for the first time from their favorite social media personalities. Indeed, all three links in the paragraph I quoted above from Thomas’s article are affiliate links. (This is not to say Thomas is doing what these creators do, I’m just pointing out how deeply rooted this economic model has become).1

As an industry, we’ve shifted from the millenial devlog to the YouTube tutorial. And while there’s absolutely nothing wrong with video as a format, the incentive for monetizing content makes developers-turned-creators perpetuate this cycle of overcomplicating software through third-party services, because at the end of the day, advertising these services and not architecting software is what pays their bills.

This trend of aggressive advertisement for a fragmented app ecosystem preys on the ever-present FOMO in the industry. If Meta and Netflix and the rest of the FAANG companies are using the latest technology… why not me?! But FAANG companies solve unique problems for their products, and thus write solutions that work for them. See also: Ruby on Rails is slow and doesn’t scale. When your app reaches a large enough amount of users to bring Rails to its knees, you’re not going to regret choosing Rails, you’re going to laugh and feel proud and incredulous that so many people have found value in your work.

The need to create content (what a terrible word tbh) about what we’re building isn’t new. There’s always been a large portion of developers who have maintained blogs throughout their careers, taking the time to explain and share their knowledge with the community. Marco Arment and David Karp famously did it while working on Tumblr. DHH did it while developing Rails. Tom Preston-Werner blogged his way through Semantic Versioning, Jekyll, and Github.

Preston-Werner even suggested README Driven Development as a solution to the problem that Next.js and the JavaScript ecosystem continues to perpetuate. He puts it this way:

I hear a lot of talk these days about TDD and BDD and Extreme Programming and SCRUM and stand up meetings and all kinds of methodologies and techniques for developing better software, but it’s all irrelevant unless the software we’re building meets the needs of those that are using it. Let me put that another way. A perfect implementation of the wrong specification is worthless. By the same principle a beautifully crafted library with no documentation is also damn near worthless. If your software solves the wrong problem or nobody can figure out how to use it, there’s something very bad going on.

And that’s one of the problems with the JS ecosystem. Rather than building software to meet the needs of its users, it builds more software to meet the needs of its developers.

Preston-Werner proposes the following solution:

Write your Readme first.

First. As in, before you write any code or tests or behaviors or stories or ANYTHING. I know, I know, we’re programmers, dammit, not tech writers! But that’s where you’re wrong. Writing a Readme is absolutely essential to writing good software. Until you’ve written about your software, you have no idea what you’ll be coding.

And to this I say:

Hey, Siri: Show me how to put ads on my Readme file and make it 10 minutes long…

In favor of Rails, Thomas explains what makes it so attractive for both small and larger teams:

Developers choose Rails today because, 20 years later, it remains the most simple and abstracted way to build a web application. Solo developers can create dynamic, real-time web applications independently (as I did with Booklet and Postcard). Enterprise teams use it to build applications with multiple models and access controls, supported by thorough testing. Rails helps small teams work faster while reducing development and maintenance costs.

He concludes that “polish fades while utility persists”, with the latter referring to Rails. But I’m doubtful that Next.js has that polish. The JS world has it backwards, imho. It prioritizes technology over people. As an enthusiast, I love JavaScript. As a developer, it’s exciting to see what can be done. It’s fun. We absolutely do need to push boundaries within web development and as it currently stands, the Next.js crowd is definitely doing that.

Rails on the other hand is mature. It’s reliable and I’m confident that my applications won’t run into issues caused not by my own doing but rather the myriad of third parties introduced into the back-end.

  1. In a reply to this post, Philip clarified that he uses Ghost as his blogging platform, which adds a ?ref parameter automatically. These are not affiliate links, and I shouldn’t have immediately assumed they were. 

Heroku Deployments

I’ve been doing a rewrite of Lettra in Rails 8 and taking note of the deployment process to Heroku1.

Start App and Create Database

$ rails new lettra --database=postgresql
$ bin/rails db:create

Create Welcome Page

$ rails g controller welcome

Create app/views/welcome/index.html.erb and add a “Hello, World” message:

<h1>Hello, World!</h1>
<p>The time is now: <time><%= Time.now %></time></p>

I’m using Time.now as a bit of a sanity check because Heroku won’t be using our local PST timezone by default.

To make this page the root page for the app, we update the config/routes.rb file with:

root "welcome#index"

At this point we should be able to see the app on port 3000 by running rails s in the CLI.

Specify Ruby Version

I’m currently on Ruby 3.3.4. Newest version as of time of writing is 3.3.7, but no need to be on the cutting edge just yet since Rails 8 was released in mid-December and it supports anything past version 3.3.

So we add the desired Ruby version in the Gemfile and run $ bundle update --ruby. We can then verify the change was successful by running $ cat Gemfile.lock | grep RUBY -a1

Create Procfile

The Procfile explicitly declares what command to execute to start the app. I’m using the Puma web server since it’s fast, tested, and has support for Rack middleware.

In the root directory we create the Procfile and add this to the file:

web: bundle exec puma -C config/puma.rb

Git

Add all and commit changes to repo.

Create a Heroku App

From CLI in app’s root directory:

$ heroku apps:create

This creates a $7/mo “web” Dyno.

Provision Heroku Database

Note from Heroku:

A mini Postgres size costs $5 a month, prorated to the minute.

$ heroku addons:create heroku-postgresql:essential-0

Environment Variables

Update: While this wasn’t an issue for the inital deployment, Heroku throws an error when attempting to run subsequent migrations on the production database with the default Rails configuration.

Heroku will throw the following error: ActiveRecord::ConnectionNotEstablished error when running rails db:migrate on Heroku.

It’ll look something like this:

ActiveRecord::ConnectionNotEstablished: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed

It’s an easy fix though, we can provide access to the Heroku database ENV variable by updating the config/database.yml.

production:
  primary: &primary_production
    <<: *default
    url: <%= ENV['DATABASE_URL'] %>
  cache:
    <<: *primary_production
    database: lettra_production_cache
    migrations_paths: db/cache_migrate
  queue:
    <<: *primary_production
    database: lettra_production_queue
    migrations_paths: db/queue_migrate
  cable:
    <<: *primary_production
    database: lettra_production_cable
    migrations_paths: db/cable_migrate

That’s all!

Deploy to Heroku

$ git push heroku main

After a successful deployment, complete these tasks as necessary:

  • Database migrations
  • Scale dynos (not needed yet)
  • Check app’s logs if issues arise

Migrate Heroku Database

$ heroku run rake db:migrate

Fix Timezone to PST from GMT

$ heroku config add: TZ="America/Los_Angeles"

Open App in Browser

$ heroku open

View App Logs

$ heroku logs

By appending the -t / --tail flag, we can see a full, live stream of the app’s logs:

$ heroku logs --tail

At this point, the starting cost for a Rails app with a Heroku backend will be max around $12.00 / month. The provision for the database is always the most expensive part of it, since not using the app does bring the cost down on the web dyno front.

  1. Since deploying to production will be the main focus of this devlog, I’m referencing this article from the Heroku Dev Center. 

Superministerium

El 27 de enero de 1932, casi un año exactamente antes de ser nombrado canciller, Hitler dio un discurso en el Düsseldorf Industrieclub, buscando respaldo económico entre los empresarios más influyentes de Alemania.

Hitler sits next to Hermann Göring at the Düsseldorf Industrieclub, while Fritz Thyssen, a wealthy industrialist who was one of Hitler’s early financial backers, speaks at the microphone, January 27, 1932.
Hitler se sienta junto a Hermann Göring en el Düsseldorf Industrieclub, mientras que Fritz Thyssen, empresario y de los primeros patrocinadores financieros de Hitler, habla ante el micrófono. (Ullstein bild / Getty)

La semana pasada se publicó un artículo en The Atlantic titulado The Oligarchs Who Came to Regret Supporting Hitler.

Entre los oligarcas que auspiciaron el movimiento político de Hitler, Alfred Hugenberg es el que más familiar nos resulta a los que vivimos las pasadas elecciones de cerca.

After cantankerous negotiation, a deal was reached: Hugenberg would deliver Hitler the chancellorship, in exchange for Hugenberg being given a cabinet post as head of a Superministerium that subsumed the ministries of economics, agriculture, and nutrition.

Tras negociaciones difíciles, se llegó a un acuerdo: Hugenberg entregaría a Hitler la cancillería, a cambio de que a Hugenberg se le asignara un puesto en el gabinete como jefe de un Superministerio que subsumiría los ministerios de economía, agricultura y nutrición.

Cuando Hugenberg fue nombrado director de aquel Superministerium, Hitler lo puso al mando de la economía del país.

As self-proclaimed “economic dictator,” Hugenberg kept pace with Hitler in outraging political opponents and much of the public. He purged ministries. He dismantled workers’ rights. He lowered the wages of his own employees by 10 percent.

Como autoproclamado “dictador económico”, Hugenberg siguió el ritmo de Hitler al ultrajar a los oponentes políticos y a gran parte del público. Purgó los ministerios. Desmanteló los derechos de los trabajadores. Bajó los salarios de sus propios empleados en un 10 por ciento.


Hace dos meses, la Comisión Federal de Elecciones (FEC) reportó que Elon Musk invirtió más de $250 millones de dólares en la campaña presidencial de Donald Trump en 2024. A cambio de su dinero, Musk fue instalado como director del Departamento de Eficiciencia Gubernamental (DOGE), una comisión particular no aprobada por el Congreso de EEUU con la tarea de reestructurar el gobierno federal y eliminar regulaciones.

En las últimas semanas, DOGE ha adquirido acceso a agencias y departamentos federales, entre los que resaltan:

  • Centros para el Control y la Prevención de Enfermedades (CDC)
  • Centros de Servicios de Medicare y Medicaid (CMS)
  • Departamento de Desarrollo Económico y Comercio (DOC)
  • Departamento de Defensa (DOD)
  • Departamento de Educación (DE)
  • Departamento de Energía (DOE)
  • Agencia de Protección Ambiental (EPA)
  • Administración Federal de Aviación (FAA)
  • Agencia Federal de Gestión de Emergencias (FEMA)
  • Departamento del Trabajo (DOL)
  • Oficina Nacional de Administración Oceánica y Atmosférica (NOAA)
  • Administración General de Servicios (GSA)
  • Administración del Seguro Social (SSA)
  • Agencia de Desarrollo Internacional (USAID)
  • Departamento de Asuntos de Veteranos (VA)
  • Departamento del Tesoro (USDT)

Anthropic y el señor Weasley

Simon Willison comparte un fragmento de la aplicación de trabajo en Anthropic:

While we encourage people to use AI systems during their role to help them work faster and more effectively, please do not use AI assistants during the application process. We want to understand your personal interest in Anthropic without mediation through an AI system, and we also want to evaluate your non-AI-assisted communication skills. Please indicate ‘Yes’ if you have read and agree.

Anthropic, online job application form

Si bien alentamos a las personas a utilizar sistemas de IA durante su función para ayudarlas a trabajar de manera más rápida y efectiva, no utilice asistentes de IA durante el proceso de solicitud. Queremos comprender su interés personal en Anthropic sin mediación a través de un sistema de IA, y también queremos evaluar sus habilidades de comunicación no asistidas por IA. Indique ‘Yes’ si ha leído y está de acuerdo.

—solicitud de empleo en Anthropic


El señor Weasley le dice a Ginny:

¿No te he enseñado una cosa? ¿Qué te he dicho siempre? No confíes en cosas que tengan la capacidad de pensar pero de las cuales no sepas dónde tienen el cerebro. ¿Por qué no me enseñaste el diario a mí o a tu madre? Un objeto tan sospechoso como ése, ¡tenía que ser cosa de magia negra!

TextMate

Uso TextMate para la edición de todo tipo de textos, ya sea para programar o para escribir cualquier cosa. Solía usar Visual Studio Code, pero me resultaba molesto gestionar todas las ventanas que abre para diferentes tipos de archivos. Por ejemplo, si estoy escribiendo en un lenguaje de marcado como Markdown (como es el caso en estos momentos), no necesito una terminal, integración con Git, ni una ventana de depuración. Con VSCode, nunca puedo centrarme únicamente en la escritura, siempre se asoman los pendientes del desarrollo de software. Esto es un problema cuando escribo artículos para proyectos de Jekyll, ya que termino por distraerme con arreglos que no son necesarios en el momento.

TextMate
TextMate

Antes de usar Visual Studio Code usaba Sublime Text. (Admito que jamás compré una licencia para este). Hace unos años, cuando fue necesario actualizar Python de su versión 2.7 a la 3.0, tuve un problema con algunos paquetes y dejó de funcionar en mi Mac. Tras reinstalarlo sin éxito varias veces, me rendí y empecé a usar Visual Studio.

Decidí usar TextMate después de verlo en el demo de Ruby on Rails 7 de DHH. Me gustó su interfaz minimalista y quise probarlo durante unas vacaciones, dedicándole tiempo no solo al uso sino también a la lectura de su documentación. El hecho de no tener la presión laboral de optimizar la productividad (🤢) me cayó como anillo al dedo, pues pude familiarizarme con el programa con toda la tranquilidad posible.

Algunas de sus funciones:

  • Pestañas
  • Integración con Git
  • Clips de texto
  • Memoria de portapapeles
  • Corrector ortográfico
  • Macros
  • Bundles
  • Comparación visual de archivos gestionados por Git
  • Vista previa de archivos

La vista previa de archivos Markdown es una de mis favoritas, ya que puedo leer fácilmente lo que escribo sin necesidad de iniciar un proceso de servidor local. Otra función muy especial de TextMate es su sistema de bundles. Es lo mismo que los paquetes de Sublime Text y las extensiones de VSCode. (De hecho los paquetes de Sublime Text que llevan el prefijo tm- se llaman así por TextMate.)

Lo que me gusta de los bundles de TM es que son muy fáciles de escribir, así que cuando empiezo a hacer algo repetitivo en mis proyectos que excede el uso de un macro, escribo un bundle. Así mi editor solo hace lo básico, a lo que le sumo mis usos personalizados y nada más.

Cabe mencionar que TextMate no es nada nuevo. Es nuevo para mí, pero la primera versión del proyecto de Allan Odgaard se remonta a octubre de 2004 y su última actualización fue hace cuatro años.

Es un software estable (usado por programadores como Marco Arment y David Heinemeier Hansson), de código abierto, modular y extensible, y no tiene nada de integración innecesaria con servicios de IA. ¿Qué más puedo pedir?

Mis playlists de Spotify

Creo que fue a finales de mi último semestre de universidad cuando empecé a crear playlists en Spotify dedicadas a cada mes. La idea era acumular las canciones con las que me topaba al salir, desde canciones que escuchaba de fondo en algún restaurante hasta lo que sonaba en el radio de un Uber. Así, a fin de año tenía una especie de scrapbook musical con los recuerdos de cada canción que fui archivando.

Antes de todo esto, el propósito de mis playlists era evocar ciertos estados de ánimo o espacios temporales. Sí, más que nada eran las cápsulas de tiempo las que me gustaba editar, y cada canción debía respetar parámetros arbitrarios que iban más allá del año de publicación. Por ejemplo, en una playlist de principios de los 2000s iban por igual La Oreja de Van Gogh, Reik y The Strokes, pero el año en que había salido el álbum no era el factor importante, sino la angustia e ímpetu con que los instrumentos de esas canciones se precipitaban hacia un destino incierto. A mi parecer, ese movimiento o impulso captura a la perfección aquella época.

Para este 2025 quiero seguir con la misma tradición de crear una playlist mensual, con las canciones que más llamen mi atención o que capturen lo que vale la pena recordar.

No sé si es una función nueva, pero ahora que tengo Spotify abierto me doy cuenta de que se pueden crear carpetas de playlists. Acabo de crear la del 2025 y la playlist de enero. Tengo tentación por añadir las buenísimas canciones que puntearon diciembre y mi viaje a Ely (en este caso la canción que más me tienta es Even the Nights Are Better de Air Supply) ya que en estos primeros días de enero sigo en modo vacaciones. Pero no se vale hacer trampa.