instance method create_table

Ruby on Rails 7.2.3

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, &block)

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.

A Hash can be used to specify the generated primary key column creation options. See add_column for available options.

: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
block block
Source
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 296
      def create_table(table_name, id: :primary_key, primary_key: nil, force: nil, **options, &block)
        validate_create_table_options!(options)
        validate_table_length!(table_name) unless options[:_uses_legacy_table_name]

        if force && options.key?(:if_not_exists)
          raise ArgumentError, "Options `:force` and `:if_not_exists` cannot be used simultaneously."
        end

        td = build_create_table_definition(table_name, id: id, primary_key: primary_key, force: force, **options, &block)

        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 296 · 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