
- Ruby on Rails - Home
- Ruby on Rails - Introduction
- Ruby on Rails - Installation
- Ruby on Rails - IDEs
- Ruby on Rails - Hello World
- Ruby on Rails - Framework
- Ruby on Rails - Directory Structure
- Ruby on Rails - Rails Console
- Ruby on Rails - Bundler
- Ruby on Rails - Examples
- Ruby on Rails - Database Setup
- Ruby on Rails - Active Records
- Ruby on Rails - Validation
- Active Record Associations
- Active Record Query
- Ruby on Rails - Migrations
- Ruby on Rails - Active Model
- Ruby on Rails - Controllers
- Cookies and Session
- Ruby on Rails - Authentication
- Ruby on Rails - Routes
- Ruby on Rails - Views
- Ruby on Rails - Rendering
- Ruby on Rails - Layouts
- Ruby on Rails - Scaffolding
- Ruby on Rails - Forms
- Ruby on Rails - Active Jobs
- Ruby on Rails - Action Text
- Ruby on Rails - Active Storage
- Ruby on Rails - JavaScript
- Ruby on Rails - Propshaft
- Ruby on Rails - ImportMap
- Ruby on Rails - AJAX
- Ruby on Rails - WebSockets
- Ruby on Rails - Action Cable
- Ruby on Rails - File Uploading
- Ruby on Rails - Send Emails
- Ruby on Rails - Rack
- Ruby on Rails - Error Handling
- Ruby on Rails - Deployment
- Ruby on Rails Resources
- Ruby on Rails - References Guide
- Ruby on Rails - Quick Guide
- Ruby on Rails - Resources
- Ruby on Rails - Discussion
- Ruby Tutorial
- Ruby Tutorial
Ruby on Rails - Migrations
Rails Migration allows you to use Ruby to define changes to your database schema, making it possible to use a version control system to keep things synchronized with the actual code. Instead of writing schema modifications in pure SQL, you can use a Ruby Domain Specific Language (DSL) to make required changes to your table structure.
This has many uses, including –
- Teams of Developers − If one person makes a schema change, the other developers just need to update, and run "rake migrate".
- Production Servers − Run "rake migrate" when you roll out a new release to bring the database up to date as well.
- Multiple Machines − If you develop on both a desktop and a laptop, or in more than one location, migrations can help you keep them all synchronized.
Migration acts as a new 'version' of the database. When you generate a model, a schema has nothing in it. Each migration modifies it to add or remove tables, columns, or indexes.
What Can Rails Migration Do?
- create_table(name, options)
- drop_table(name)
- rename_table(old_name, new_name)
- add_column(table_name, column_name, type, options)
- rename_column(table_name, column_name, new_column_name)
- change_column(table_name, column_name, type, options)
- remove_column(table_name, column_name)
- add_index(table_name, column_name, index_type)
- remove_index(table_name, column_name)
Migrations support all the basic data types − The following is the list of data types that migration supports −
- string − for small data types such as a title.
- text − for longer pieces of textual data, such as the description.
- integer − for whole numbers.
- float − for decimals.
- datetime and timestamp − store the date and time into a column.
- date and time − store either the date only or time only.
- binary − for storing data such as images, audio, or movies.
- Boolean − for storing true or false values.
Valid column options are − The following is the list of valid column options.
- comment − Adds a comment for the column.
- collation − Specifies the collation for a string or text column.
- default − Allows to set a default value on the column. Use nil for NULL. (:default => "blah")
- limit − Sets the maximum number of characters for a string column and the maximum number of bytes for text/binary/integer columns. (:limit => "50")
- null − Allows or disallows NULL values in the column. (:null => false)
- precision − Specifies the precision for decimal/numeric/datetime/time columns.
- scale − specifies the scale for the decimal and numeric columns.
Create the Migrations
In the previous chapter, you have created Book and Subject models with the following commands −
malhar@ubuntu:~/library$ rails generate model Book title:string price:float subject:references malhar@ubuntu:~/library$ rails generate model Subject name:string
Note that using subject:references in the Book model automatically creates a subject_id foreign key column in the books table.
Migration files are created inside the db/migrate folder, one for each migration class. The name of the file is of the form YYYYMMDDHHMMSS_create_books.rb, which has the following code −
class CreateBooks < ActiveRecord::Migration[8.0] def change create_table :books do |t| t.string :title t.float :price t.references :subject, null: false, foreign_key: true t.timestamps end end end
Similarly, the create_subjects.rb file in db\migrate folder has the following code −
class CreateSubjects < ActiveRecord::Migration[8.0] def change create_table :subjects do |t| t.string :name t.timestamps end end end
Make sure that you have created associations between Book and Subject model. The Book class in book.rb file has belongs_to relation with subjects
class Book < ApplicationRecord belongs_to :subject end
Similarly, there is a has_many relationship between Book and subjects (subject.rb)
class Subject < ApplicationRecord has_many :books end
NOTE − Before running the migration generator, it is recommended to clean the existing migrations generated by model generators.
The db:migrate command
Now that you have created all the required migration files. It is time to execute them against the database. To do this, go to a command prompt and go to the library directory in which the application is located, and then run the rails migrate command as follows −
malhar@ubuntu:~/library$ rails db:migrate == 20250305181938 CreateBooks: migrating ====================================== -- create_table(:books) -> 0.0188s == 20250305181938 CreateBooks: migrated (0.0054s)=============================== == 20250305182034 CreateSubjects: migrating =================================== -- create_table(:subjects) -> 0.0069s == 20250305182034 CreateSubjects: migrated (0.0084s) ==========================
Rails creates db\schema.rb file to define the structure of the tables in the database.
ActiveRecord::Schema[8.0].define(version: 2025_03_05_182034) do create_table "books", force: :cascade do |t| t.string "title" t.float "price" t.integer "subject_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false t.index ["subject_id"], name: "index_books_on_subject_id" end create_table "subjects", force: :cascade do |t| t.string "name" t.datetime "created_at", null: false t.datetime "updated_at", null: false end add_foreign_key "books", "subjects" end
The migration step creates a db/seeds.rb file is used to populate the database with initial or default data when setting up a Rails application.
Edit the file and add the following statement in it −
Subject.create([ { name: "Physics" }, { name: "Mathematics" }, { name: "Chemistry" }, { name: "Psychology" }, { name: "Geology" } ])
and then run −
malhar@ubuntu:~/library$ rails db:seed
This inserts the records in the Subject table.
generate migration
This command is used to modify the structure of an existing table, such as adding or removing a column.
Adding Columns
When you want to add a new column to an existing table in your database, you can use a migration with the format "AddColumnToTable" followed by a list of column names and types.
To add a new column named author in the book model, use the following command −
malhar@ubuntu:~/library$ rails generate migration AddAuthorToBooks author:string
This creates a migration file −
class AddAuthorToBooks < ActiveRecord::Migration[8.0] def change add_column :books, :author, :string end end
You then apply it using the migrate command again:
malhar@ubuntu:~/library$ rails db:migrate
Removing Columns
Similarly, if the migration name is of the form "RemoveColumnFromTable" and is followed by a list of column names
malhar@ubuntu:~/library$ rails generate migration RemoveAuthorFromBooks author:string
The change() Method
Whenever a model structure is altered, the migration command defines the change() method to perform corresponding action (add_column, remove_column etc). It supports the following actions −
- add_column
- add_foreign_key
- add_index
- add_reference
- create_join_table
- create_table
- drop_table
- remove_column
- remove_foreign_key
- remove_index
- remove_reference
- remove_timestamps
- rename_column
- rename_index
- rename_table
You can also use the up and down methods instead of the change method (change method was introduced in Rails 5.0, and is the standard way to modify the migrations, although up/down methods are still supported but not recommended).
The method up is used when migrating to a new version, down is used to roll back any changes if needed.
Other Migration Commands
In addition to the rails db:migrate command, the following migration commands are useful.
Rolling Back
If you have made a mistake in the model definition, rather than tracking down the version number associated with the previous migration you can run:
malhar@ubuntu:~/library$ rails db:rollback
This will roll back the ldatabase to the latest migration, either by reverting the change method or by running the down method. If you need to undo several migrations you can provide a STEP parameter:
malhar@ubuntu:~/library$ rails db:rollback STEP=2
Setting Up the Database
The rails db:setup command will create the database, load the schema, and initialize it with the seed data.
Resetting the Database
The rails db:reset command will drop the database and set it up again. This is equivalent to rails db:drop db:setup command.