# Why You Should Avoid Models in Rails Migrations

DevFeed: [Why You Should Avoid Models in Rails Migrations](<https://devfeed.tech/articles/why-you-should-avoid-models-in-rails-migrations-21078.md>)

Original publisher: [Read original article](<https://jakeyesbeck.com/2021/04/10/avoid-models-in-migrations/>)

Published: 2021-04-10T12:00:00Z

Content type: article

Language: en

Sources: [Jake Yesbeck](<https://devfeed.tech/sources/jake-yesbeck.md>)

Topics: [Rails](<https://devfeed.tech/topics/rails.md>), [migration](<https://devfeed.tech/topics/migration.md>), [Code](<https://devfeed.tech/topics/code.md>), [Databases](<https://devfeed.tech/topics/databases.md>), [App](<https://devfeed.tech/topics/app.md>)

Tags: [activerecord](<https://devfeed.tech/tags/activerecord.md>), [code](<https://devfeed.tech/tags/code.md>), [database](<https://devfeed.tech/tags/database.md>), [migration](<https://devfeed.tech/tags/migration.md>), [rails](<https://devfeed.tech/tags/rails.md>), [us](<https://devfeed.tech/tags/us.md>)

## AI overview

This article explains why Rails migrations should avoid relying on application models. A model rename can cause an older migration that calls the model to fail when another developer runs it later. It recommends using SQL through the base database connection or defining a temporary model inside the migration so migrations depend on stable database structure rather than changing application code.

## Source excerpt

Humble Beginnings A simple Rails application exists with two models, Books and Authors. class Book < ApplicationRecord belongs_to :author end class Author < ApplicationRecord has_many :books end After some domestic success, this simple Rails app goes international. A new column is required on the books table: country to denote which country published the Book. A Reasonable Migration To preserve data integrity, the country column should not allow null since null isn't a country. Existing books also need to have a country set. This is all accomplished within a single migration in 3 steps: Add a column Update column for existing books with a reasonable value Add a constraint that the column can not be null class AddCountryToBooks < ActiveRecord::Migration[6.1] def up add_column :books, :country, :string, length: 2 Book.update_all(country: 'US') change_column_null :books, :country, false end def down remove_column :books, :country end end This migration does the job but has hidden implications. A developer working in isolation may never run into the trap lurking in this code, but a team could. Working with Others Two developers work on this application, divvying up the wild world of books and authors but maintaining healthy work life balances. One developer goes on vacation and has a surprise waiting for them when they return. Developer 1 👩💻 Developer 2 👨💻 Day 1 Write Code Write Code Day 2 😎 Time Off 🏗 Create Migration Day 3 😎 Time Off 📛 Rename Class Day 4 😎 Time Off Write Code Day 5 Run Migrations -> 🔥 Error Write Code While Developer 1 was away, the Developer 2 was busy. They wrote the above migration, updated existing data and then a new feature request was completed: A model rename. Developer 1 returns, updates their local environment, and runs rake db:migrate: == 20210407191819 AddCountryToBooks: migrating =================== -- add_column(:books, :country, :string, {:length=>2}) -> 0.0015s rake aborted! StandardError: An error has occurred, this and all la