Loading Rails models during migrations can lead to problems during seed
Consider this scenario..
You have a users table, created like this:
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 end end end
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| user.email.split('@').first end end end
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 end end
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]') end
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:
- Run `rails db:seed` separately so that environment is reloaded
- Manually reload column names in `seeds.rb` via `User.reset_column_information` before calling the `.create` method.
- 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:
https://stackoverflow.com/questions/44188485/error-when-running-migrate-and-seed-together
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: https://github.com/mzrnsh/jekyllwind
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: https://github.com/mzrnsh/jekyllwind
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.
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