
This is how to make migration file about create_table method in Ruby on Rails. The create_table method is one of the most fundamental, but most of the time, will be generated for you from using a model or scaffold generator.
Contents
Creating a migration file - rails generate XXX
There are two ways to generate a migration file in which create_table method is defined by rails generate command.
$ rails generate migration CreateXXX
$ rails generate model XXX
For rails generate migration CreateXXX
According to the Rails, in the case of the users table, it is recommended to add the plural "s" like Users.
Terminal
// When creating users table. $ rails generate migration CreateUsers Running via Spring preloader in process 63289 invoke active_record create db/migrate/20200412213209_create_users.rb$ cat db/migrate/20200412213209_create_users.rb class CreateUsers < ActiveRecord::Migration[6.0] def change create_table :users do |t| end end end
For rails generate model XXX
According to the Rails, in the case of the users table, it is recommended to use singular system like User because it is a model class creation.
Terminal
// When creating users table. $ rails generate model User Running via Spring preloader in process 66706 invoke active_record create db/migrate/20200413165906_create_users.rb create app/models/user.rb invoke test_unit create test/models/user_test.rb create test/fixtures/users.yml $ cat db/migrate/20200413163138_create_users.rb class CreateUsers < ActiveRecord::Migration[6.0] def change create_table :users do |t| t.timestamps end end end $ cat app/models/users.rb class Users < ApplicationRecord end
When to not generate id column automatically - id: false
Set id: false option.
YYYYMMDDhhmmss_create_users.rb
class CreateUsers < ActiveRecord::Migration[6.0] def change create_table :users, id: false do |t| ... end end end
When specifying the primary key except id column - primary_key: :COLUMN
Specify the primary_key: :COLUMN option. For example, if COLUMN = hoge, the hoge column will be the primary key.
When setting the primary_key: option on the create_table method.
YYYYMMDDhhmmss_create_users.rb
class CreateUsers < ActiveRecord::Migration[6.0] def change create_table :users, primary_key: :hoge do |t| t.timestamps end end end
Terminal
// For MySQL mysql> DESC users; +------------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+-------------+------+-----+---------+----------------+ | hoge | bigint(20) | NO | PRI | NULL | auto_increment | | created_at | datetime(6) | NO | | NULL | | | updated_at | datetime(6) | NO | | NULL | | +------------+-------------+------+-----+---------+----------------+
When setting the primary_key: option on a column.
YYYYMMDDhhmmss_create_users.rb
class CreateUsers < ActiveRecord::Migration[6.0] def change create_table :users, id: false do |t| t.integer :hoge, limit: 8, auto_increment: true, primary_key: true t.timestamps end end end
Terminal
// For MySQL mysql> DESC users; +------------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+-------------+------+-----+---------+----------------+ | hoge | bigint(20) | NO | PRI | NULL | auto_increment | | created_at | datetime(6) | NO | | NULL | | | updated_at | datetime(6) | NO | | NULL | | +------------+-------------+------+-----+---------+----------------+
Check each default data type
YYYYMMDDhhmmss_create_users.rb
class CreateUsers < ActiveRecord::Migration[6.0] def change create_table :users do |t| t.integer :col1 t.string :col2 t.text :col3 t.float :col4 t.decimal :col5 t.datetime :col6 t.timestamp :col7 t.time :col8 t.date :col9 t.binary :col10 t.boolean :col11 t.timestamps end end end
Terminal
// For MySQL mysql> DESC users; +------------+---------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+---------------+------+-----+---------+----------------+ | id | bigint(20) | NO | PRI | NULL | auto_increment | | col1 | int(11) | YES | | NULL | | | col2 | varchar(255) | YES | | NULL | | | col3 | text | YES | | NULL | | | col4 | float | YES | | NULL | | | col5 | decimal(10,0) | YES | | NULL | | | col6 | datetime | YES | | NULL | | | col7 | timestamp | YES | | NULL | | | col8 | time | YES | | NULL | | | col9 | date | YES | | NULL | | | col10 | blob | YES | | NULL | | | col11 | tinyint(1) | YES | | NULL | | | created_at | datetime(6) | NO | | NULL | | | updated_at | datetime(6) | NO | | NULL | | +------------+---------------+------+-----+---------+----------------+
Set NOT NULL to column - null: false
Set null: false option to a column.
YYYYMMDDhhmmss_create_users.rb
class CreateUsers < ActiveRecord::Migration[6.0] def change create_table :users do |t| t.integer :col1, null: false end end end
Terminal
// For MySQL mysql> DESC users; +-------+------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+------------+------+-----+---------+----------------+ | id | bigint(20) | NO | PRI | NULL | auto_increment | | col1 | int(11) | NO | | NULL | | +-------+------------+------+-----+---------+----------------+
Set DEFAULT to column - default: XXX
Set default: XXX option to a column.
YYYYMMDDhhmmss_create_users.rb
class CreateUsers < ActiveRecord::Migration[6.0] def change create_table :users do |t| t.integer :col1, default: 1 t.string :col2, default: 'Hi' t.boolean :col3, default: true end end end
Terminal
// For MySQL mysql> DESC users; +-------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+--------------+------+-----+---------+----------------+ | id | bigint(20) | NO | PRI | NULL | auto_increment | | col1 | int(11) | YES | | 1 | | | col2 | varchar(255) | YES | | Hi | | | col3 | tinyint(1) | YES | | 1 | | +-------+--------------+------+-----+---------+----------------+
Set UNIQUE KEY to column - index: { unique: true }
Set index: { unique: true } option to a column.
YYYYMMDDhhmmss_create_users.rb
class CreateUsers < ActiveRecord::Migration[6.0] def change create_table :users do |t| t.integer :col1, index: { unique: true } end end end
Terminal
// For MySQL mysql> DESC users; +-------+------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+------------+------+-----+---------+----------------+ | id | bigint(20) | NO | PRI | NULL | auto_increment | | col1 | int(11) | YES | UNI | NULL | | +-------+------------+------+-----+---------+----------------+
Set COMMENT to column - comment: 'XXX'
Set comment: 'XXX' option to a column.
YYYYMMDDhhmmss_create_users.rb
class CreateUsers < ActiveRecord::Migration[6.0] def change create_table :users do |t| t.integer :col1, comment: 'COMMENT' end end end
Set FOREIGN KEY to column - t.references foreign_key: XXX
Set references type and foreign_key: XXX option to a column.
YYYYMMDDhhmmss_create_users.rb
class CreateUsers < ActiveRecord::Migration[6.0] def change create_table :users do |t| t.integer :col1 end end end
YYYYMMDDhhmmss_create_posts.rb
class CreatePosts < ActiveRecord::Migration[6.0] def change create_table :posts do |t| # When setting foreign key to the id column in users table. # t.references :user, null: false, foreign_key: true # In addition, for setting ON DELETE CASCADE ON UPDATE CASCADE. t.references :user, null: false, foreign_key: {on_delete: :cascade, on_update: :cascade} end end end
Terminal
// For MySQL mysql> DESC users; +-------+------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+------------+------+-----+---------+----------------+ | id | bigint(20) | NO | PRI | NULL | auto_increment | | col1 | int(11) | YES | | NULL | | +-------+------------+------+-----+---------+----------------+ mysql> DESC users; +---------+------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +---------+------------+------+-----+---------+----------------+ | id | bigint(20) | NO | PRI | NULL | auto_increment | | user_id | bigint(20) | NO | MUL | NULL | | +---------+------------+------+-----+---------+----------------+
Set PRIMARY KEY and FOREIGN KEY to the same column - t.references primary_key: true foreign_key: XXX
Set references type, primary_key: true and foreign_key: XXX option to a column.
YYYYMMDDhhmmss_create_users.rb
class CreateUsers < ActiveRecord::Migration[6.0] def change create_table :users do |t| t.integer :col1 end end end
YYYYMMDDhhmmss_create_posts.rb
class CreatePosts < ActiveRecord::Migration[6.0] def change create_table :posts, id: false do |t| t.references :user, null: false, primary_key: true, foreign_key: {on_delete: :cascade, on_update: :cascade} end end end
Terminal
// For MySQL mysql> DESC users; +-------+------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+------------+------+-----+---------+----------------+ | id | bigint(20) | NO | PRI | NULL | auto_increment | | col1 | int(11) | YES | | NULL | | +-------+------------+------+-----+---------+----------------+ mysql> DESC posts; +---------+------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +---------+------------+------+-----+---------+----------------+ | user_id | bigint(20) | NO | PRI | NULL | auto_increment | +---------+------------+------+-----+---------+----------------+ mysql> SHOW CREATE TABLE posts; CREATE TABLE `posts` ( `user_id` bigint(20) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`user_id`), KEY `index_posts_on_user_id` (`user_id`), CONSTRAINT `fk_rails_5b5ddfd518` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci