class ActiveRecord::ConnectionAdapters::TableDefinition - activerecord-4.2.5.2 Documentation

# class ActiveRecord::ConnectionAdapters::TableDefinition

Represents the schema of an SQL table in an abstract way. This class provides methods for manipulating the schema representation.

Inside migration files, the `t` object in `create_table` is actually of this type:

    class SomeMigration < ActiveRecord::Migration
      def up
        create_table :foo do |t|
          puts t.class  # => "ActiveRecord::ConnectionAdapters::TableDefinition"
        end
      end

      def down
        ...
      end
    end

The table definitions The Columns are stored as a ColumnDefinition in the `columns` attribute.

### Attributes

as[R]
foreign_keys[R]
indexes[RW]

An array of ColumnDefinition objects, representing the column changes that have been defined.

name[R]
options[R]
temporary[R]

### Public Class Methods

new(types, name, temporary, options, as = nil) click to toggle source

    # File lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 99
    def initialize(types, name, temporary, options, as = nil)
      @columns_hash = {}
      @indexes = {}
      @foreign_keys = {}
      @native = types
      @temporary = temporary
      @options = options
      @as = as
      @name = name
    end

### Public Instance Methods

[](name) click to toggle source

Returns a ColumnDefinition for the column with name `name`.

    # File lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 119
    def [](name)
      @columns_hash[name.to_s]
    end

belongs_to(*args)
Alias for: references
column(name, type, options = {}) click to toggle source

Instantiates a new column for the table. The `type` parameter is normally one of the migrations native types, which is one of the following: `:primary_key`, `:string`, `:text`, `:integer`, `:float`, `:decimal`, `:datetime`, `:time`, `:date`, `:binary`, `:boolean`.

You may use a type not in this list as long as it is supported by your database (for example, “polygon” in MySQL), but this will not be database agnostic and should usually be avoided.

Available options are (none of these exists by default):

- `:limit` - Requests a maximum column length. This is number of characters for `:string` and `:text` columns and number of bytes for `:binary` and `:integer` columns.

- `:default` - The column's default value. Use nil for NULL.

- `:null` - Allows or disallows `NULL` values in the column. This option could have been named `:null_allowed`.

- `:precision` - Specifies the precision for a `:decimal` column.

- `:scale` - Specifies the scale for a `:decimal` column.

- `:index` - Create an index for the column. Can be either `true` or an options hash.

Note: The precision is the total number of significant digits and the scale is the number of digits that can be stored following the decimal point. For example, the number 123.45 has a precision of 5 and a scale of 2. A decimal with a precision of 5 and a scale of 2 can range from -999.99 to 999.99.

Please be aware of different RDBMS implementations behavior with `:decimal` columns:

- The SQL standard says the default scale should be 0, `:scale` <= `:precision`, and makes no comments about the requirements of `:precision`.

- MySQL: `:precision` [1..63], `:scale` [0..30]. Default is (10,0).

- PostgreSQL: `:precision` [1..infinity], `:scale` [0..infinity]. No default.

- SQLite2: Any `:precision` and `:scale` may be used. Internal storage as strings. No default.

- SQLite3: No restrictions on `:precision` and `:scale`, but the maximum supported `:precision` is 16. No default.

- Oracle: `:precision` [1..38], `:scale` [-84..127]. Default is (38,0).

- DB2: `:precision` [1..63], `:scale` [0..62]. Default unknown.

- SqlServer?: `:precision` [1..38], `:scale` [0..38]. Default (38,0).

This method returns `self`.

## Examples¶ ↑

    # Assuming +td+ is an instance of TableDefinition
    td.column(:granted, :boolean)
    # granted BOOLEAN

    td.column(:picture, :binary, limit: 2.megabytes)
    # => picture BLOB(2097152)

    td.column(:sales_stage, :string, limit: 20, default: 'new', null: false)
    # => sales_stage VARCHAR(20) DEFAULT 'new' NOT NULL

    td.column(:bill_gates_money, :decimal, precision: 15, scale: 2)
    # => bill_gates_money DECIMAL(15,2)

    td.column(:sensor_reading, :decimal, precision: 30, scale: 20)
    # => sensor_reading DECIMAL(30,20)

    # While <tt>:scale</tt> defaults to zero on most databases, it
    # probably wouldn't hurt to include it.
    td.column(:huge_integer, :decimal, precision: 30)
    # => huge_integer DECIMAL(30)

    # Defines a column with a database-specific type.
    td.column(:foo, 'polygon')
    # => foo polygon

## Short-hand examples¶ ↑

Instead of calling `column` directly, you can also work with the short-hand definitions for the default types. They use the type as the method name instead of as a parameter and allow for multiple columns to be defined in a single statement.

What can be written like this with the regular calls to column:

    create_table :products do |t|
      t.column :shop_id,     :integer
      t.column :creator_id,  :integer
      t.column :item_number, :string
      t.column :name,        :string, default: "Untitled"
      t.column :value,       :string, default: "Untitled"
      t.column :created_at,  :datetime
      t.column :updated_at,  :datetime
    end
    add_index :products, :item_number

can also be written as follows using the short-hand:

    create_table :products do |t|
      t.integer :shop_id, :creator_id
      t.string  :item_number, index: true
      t.string  :name, :value, default: "Untitled"
      t.timestamps null: false
    end

There's a short-hand method for each of the type values declared at the top. And then there's #timestamps that'll add `created_at` and `updated_at` as datetimes.

#references will add an appropriately-named _id column, plus a corresponding _type column if the `:polymorphic` option is supplied. If `:polymorphic` is a hash of options, these will be used when creating the `_type` column. The `:index` option will also create an index, similar to calling `add_index`. So what can be written like this:

    create_table :taggings do |t|
      t.integer :tag_id, :tagger_id, :taggable_id
      t.string  :tagger_type
      t.string  :taggable_type, default: 'Photo'
    end
    add_index :taggings, :tag_id, name: 'index_taggings_on_tag_id'
    add_index :taggings, [:tagger_id, :tagger_type]

Can also be written as follows using references:

    create_table :taggings do |t|
      t.references :tag, index: { name: 'index_taggings_on_tag_id' }
      t.references :tagger, polymorphic: true, index: true
      t.references :taggable, polymorphic: { default: 'Photo' }
    end

    # File lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 256
    def column(name, type, options = {})
      name = name.to_s
      type = type.to_sym
      options = options.dup

      if @columns_hash[name] && @columns_hash[name].primary_key?
        raise ArgumentError, "you can't redefine the primary key column '#{name}'. To define a custom primary key, pass { id: false } to create_table."
      end

      index_options = options.delete(:index)
      index(name, index_options.is_a?(Hash) ? index_options : {}) if index_options
      @columns_hash[name] = new_column_definition(name, type, options)
      self
    end

columns() click to toggle source

    # File lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 110
    def columns; @columns_hash.values; end

index(column_name, options = {}) click to toggle source

Adds index options to the indexes hash, keyed by column name This is primarily used to track indexes that need to be created after the table

    index(:account_id, name: 'index_projects_on_account_id')

    # File lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 287
    def index(column_name, options = {})
      indexes[column_name] = options
    end

primary_key(name, type = :primary_key, options = {}) click to toggle source

Appends a primary key definition to the table definition. Can be called multiple times, but this is probably not a good idea.

    # File lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 114
    def primary_key(name, type = :primary_key, options = {})
      column(name, type, options.merge(:primary_key => true))
    end

references(*args) click to toggle source

Adds a reference.

    t.references(:user)
    t.belongs_to(:supplier, foreign_key: true)

See ActiveRecord::ConnectionAdapters::SchemaStatements#add_reference for details of the options you can use.

    # File lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 312
    def references(*args)
      options = args.extract_options!
      polymorphic = options.delete(:polymorphic)
      index_options = options.delete(:index)
      foreign_key_options = options.delete(:foreign_key)
      type = options.delete(:type) || :integer

      if polymorphic && foreign_key_options
        raise ArgumentError, "Cannot add a foreign key on a polymorphic relation"
      end

      args.each do |col|
        column("#{col}_id", type, options)
        column("#{col}_type", :string, polymorphic.is_a?(Hash) ? polymorphic : options) if polymorphic
        index(polymorphic ? %w(type id).map { |t| "#{col}_#{t}" } : "#{col}_id", index_options.is_a?(Hash) ? index_options : {}) if index_options
        if foreign_key_options
          to_table = Base.pluralize_table_names ? col.to_s.pluralize : col.to_s
          foreign_key(to_table, foreign_key_options.is_a?(Hash) ? foreign_key_options : {})
        end
      end
    end

Also aliased as: belongs_to
remove_column(name) click to toggle source

    # File lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 271
    def remove_column(name)
      @columns_hash.delete name.to_s
    end

timestamps(*args) click to toggle source

Appends `:datetime` columns `:created_at` and `:updated_at` to the table. See ActiveRecord::ConnectionAdapters::SchemaStatements#add_timestamps

    t.timestamps null: false

    # File lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 299
    def timestamps(*args)
      options = args.extract_options!
      emit_warning_if_null_unspecified(:timestamps, options)
      column(:created_at, :datetime, options)
      column(:updated_at, :datetime, options)
    end

### Private Instance Methods

aliased_types(name, fallback) click to toggle source

    # File lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 362
    def aliased_types(name, fallback)
      'timestamp' == name ? :datetime : fallback
    end

create_column_definition(name, type) click to toggle source

    # File lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 354
    def create_column_definition(name, type)
      ColumnDefinition.new name, type
    end

native() click to toggle source

    # File lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 358
    def native
      @native
    end