We are living as nomad in Cyprus !!
ruby on rails

[Rails] How to make migration file about create_table method

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
Search by keywords

Select Language

/

Follow us by