Giorgi Mzrnsh


Website GitHub X

Loading Rails models during migrations can lead to problems during seed

Consider this scenario..

You have a users table, created like this:

# Migration 1
class CreateUsers < ActiveRecord::Migration[7.0]
  def change
    create_table :users do |t|
      t.string :email, null: false

Then you decide to add `:name` attribute to your User model, but at this time you already have some User records, so you want to make sure existing ones also get the name

# Migration 2
class AddNameToUsers < ActiveRecord::Migration[7.0]
  def change
    add_column :users, :name, :string

    User.find_each do |user|'@').first

But later, you decided to remove the `:name` attribute. Maybe you wanted to add separate fields for first name and last name, or maybe for another reason:

# Migration 3
class RemoveNameFromUsers < ActiveRecord::Migration[7.0]
  def change
    remove_column :users, :name, :string

At some point, you also took care of the seeds file, so that when a new developer joins the project, they can have some data in their fresh database:

# db/seeds.rb
if Rails.env.development?
  User.create(email: '[email protected]')

Now that developer joins (or you buy a new computer!) and the app needs to be installed from scratch. The typical db commands are run in the terminal:

rails db:drop db:create db:migrate db:seed

So far so good, right? Wrong! This won't work and `PG::UndefinedColumn` error will be raised (well, if you are using PG as your database, that is).

The reason being, you already loaded the User model in migration #2, and at that point, it had a `:name` attribute. But by the time your db is seeded, the column name is still there, but the column itself is gone, hence the error.

Potential fixes:

  1. Run `rails db:seed` separately so that environment is reloaded
  2. Manually reload column names in `seeds.rb` via `User.reset_column_information` before calling the `.create` method.
  3. Get rid of the old migration files (or edit them), because the data migration in that file was probably a one-off thing, and it is already applied to the production database. And the new dev setting up a new db doesn't have historic data, so data migration isn't needed either.

ChatGPT didn't help me figure this out, but weirdly enough, SO did:

GitHub has a "template repository" feature

This allows users to create fresh repositories based on the template repository, without creating forks, or keeping the git history. Handy for boilerplates or starter projects.

It's located right under the project name in settings, and once on, a new green button "Use this template" appears on repository home page. You can see it in action on my Jekyll+Tailwind boilerplate:

Netlify serves Jekyll 404 pages out of box

I have built many Jekyll websites, but I kind of always forgot to add a 404 page. I knew it works out of box on local server (Webrick) and GH Pages.

Well, today I learned that Netlify respects our time as well and placing a `404.html` page in the root will also work magically over there, with 0 config.

SimpleHTTPServer has become even simpler in Python 3

One of the simplest ways to serve a static website on locally has forever been opening up a terminal window, "cd"-ing to the website folder and running Python's SimpleHTTPServer in it:

python -m SimpleHTTPServer 8000 

Today I learned that the command has become a bit more memorable in Python 3:

python3 -m http.server

Regarding privacy concerns, it's simple - we don't sell your data. In fact, we try to use privacy-focused software/services like Fathom Analytics whenever we use any third-party services.