instance method create_table

Ruby on Rails 7.0.10

Since v2.2.3

Available in: v2.2.3 v2.3.18 v3.0.20 v3.1.12 v3.2.22.5 v4.0.13 v4.1.16 v4.2.9 v5.2.8.1 v6.0.6 v6.1.7.10 v7.0.10 v7.1.6 v7.2.3 v8.0.4 v8.1.2

Signature

create_table(table_name, id: :primary_key, primary_key: nil, force: nil, **options)

Creates a new table with the name table_name. table_name may either be a String or a Symbol.

There are two ways to work with #create_table. You can use the block form or the regular form, like this:

Block form

# create_table() passes a TableDefinition object to the block.
# This form will not only create the table, but also columns for the
# table.

create_table(:suppliers) do |t|
  t.column :name, :string, limit: 60
  # Other fields here
end

Block form, with shorthand

# You can also use the column types as method calls, rather than calling the column method.
create_table(:suppliers) do |t|
  t.string :name, limit: 60
  # Other fields here
end

Regular form

# Creates a table called 'suppliers' with no columns.
create_table(:suppliers)
# Add a column to 'suppliers'.
add_column(:suppliers, :name, :string, {limit: 60})

The options hash can include the following keys:

:id

Whether to automatically add a primary key column. Defaults to true. Join tables for ActiveRecord::Base.has_and_belongs_to_many should set it to false.

A Symbol can be used to specify the type of the generated primary key column.

:primary_key

The name of the primary key, if one is to be added automatically. Defaults to id. If :id is false, then this option is ignored.

If an array is passed, a composite primary key will be created.

Note that Active Record models will automatically detect their primary key. This can be avoided by using self.primary_key= on the model to define the key explicitly.

:options

Any extra options you want appended to the table definition.

:temporary

Make a temporary table.

:force

Set to true to drop the table before creating it. Set to :cascade to drop dependent objects as well. Defaults to false.

:if_not_exists

Set to true to avoid raising an error when the table already exists. Defaults to false.

:as

SQL to use to generate the table. When this option is used, the block is ignored, as are the :id and :primary_key options.

Add a backend specific option to the generated SQL (MySQL)
create_table(:suppliers, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8mb4')

generates:

CREATE TABLE suppliers (
  id bigint auto_increment PRIMARY KEY
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
Rename the primary key column
create_table(:objects, primary_key: 'guid') do |t|
  t.column :name, :string, limit: 80
end

generates:

CREATE TABLE objects (
  guid bigint auto_increment PRIMARY KEY,
  name varchar(80)
)
Change the primary key column type
create_table(:tags, id: :string) do |t|
  t.column :label, :string
end

generates:

CREATE TABLE tags (
  id varchar PRIMARY KEY,
  label varchar
)
Create a composite primary key
create_table(:orders, primary_key: [:product_id, :client_id]) do |t|
  t.belongs_to :product
  t.belongs_to :client
end

generates:

CREATE TABLE orders (
    product_id bigint NOT NULL,
    client_id bigint NOT NULL
);

ALTER TABLE ONLY "orders"
  ADD CONSTRAINT orders_pkey PRIMARY KEY (product_id, client_id);
Do not add a primary key column
create_table(:categories_suppliers, id: false) do |t|
  t.column :category_id, :bigint
  t.column :supplier_id, :bigint
end

generates:

CREATE TABLE categories_suppliers (
  category_id bigint,
  supplier_id bigint
)
Create a temporary table based on a query
create_table(:long_query, temporary: true,
  as: "SELECT * FROM orders INNER JOIN line_items ON order_id=orders.id")

generates:

CREATE TEMPORARY TABLE long_query AS
  SELECT * FROM orders INNER JOIN line_items ON order_id=orders.id

See also TableDefinition#column for details on how to create columns.

Parameters

table_name req
id key = :primary_key
primary_key key = nil
force key = nil
options keyrest
Source
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 300
      def create_table(table_name, id: :primary_key, primary_key: nil, force: nil, **options)
        td = create_table_definition(table_name, **extract_table_options!(options))

        if id && !td.as
          pk = primary_key || Base.get_primary_key(table_name.to_s.singularize)

          if id.is_a?(Hash)
            options.merge!(id.except(:type))
            id = id.fetch(:type, :primary_key)
          end

          if pk.is_a?(Array)
            td.primary_keys pk
          else
            td.primary_key pk, id, **options
          end
        end

        yield td if block_given?

        if force
          drop_table(table_name, force: force, if_exists: true)
        else
          schema_cache.clear_data_source_cache!(table_name.to_s)
        end

        result = execute schema_creation.accept td

        unless supports_indexes_in_create?
          td.indexes.each do |column_name, index_options|
            add_index(table_name, column_name, **index_options, if_not_exists: td.if_not_exists)
          end
        end

        if supports_comments? && !supports_comments_in_create?
          if table_comment = td.comment.presence
            change_table_comment(table_name, table_comment)
          end

          td.columns.each do |column|
            change_column_comment(table_name, column.name, column.comment) if column.comment.present?
          end
        end

        result
      end

Defined in activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb line 300 · View on GitHub · Improve this page · Find usages on GitHub

Defined in ActiveRecord::ConnectionAdapters::SchemaStatements

Type at least 2 characters to search.

↑↓ navigate · open · esc close