class ActiveRecord::ConnectionAdapters::TableDefinition
The Columns are stored as a ColumnDefinition in the columns
attribute.
The table definitions
end
end
…
def self.down
end
end
puts t.class # => “ActiveRecord::ConnectionAdapters::TableDefinition”
create_table :foo do |t|
def self.up
class SomeMigration < ActiveRecord::Migrationchange_table
is actually of this type:
Inside migration files, the t
object in create_table
and
provides methods for manipulating the schema representation.
Represents the schema of an SQL table in an abstract way. This class
def [](name)
def [](name) @columns.find {|column| column.name.to_s == name.to_s} end
def column(name, type, options = {})
t.references :taggable, :polymorphic => { :default => 'Photo' }
t.references :tagger, :polymorphic => true
t.references :tag
create_table :taggings do |t|
Can also be written as follows using references:
end
t.string :taggable_type, :default => 'Photo'
t.string :tagger_type
t.integer :tag_id, :tagger_id, :taggable_id
create_table :taggings do |t|
used when creating the _type column. So what can be written like this:
column if the :polymorphic option is supplied. If :polymorphic is a hash of options, these will be
TableDefinition#references will add an appropriately-named _id column, plus a corresponding _type
TableDefinition#timestamps that'll add created_at and +updated_at+ as datetimes.
There's a short-hand method for each of the type values declared at the top. And then there's
end
t.timestamps
t.string :name, :value, :default => "Untitled"
t.integer :shop_id, :creator_id
create_table :products do |t|
Can also be written as follows using the short-hand:
end
t.column "updated_at", :datetime
t.column "created_at", :datetime
t.column "value", :string, :default => "Untitled"
t.column "name", :string, :default => "Untitled"
t.column "creator_id", :integer
t.column "shop_id", :integer
create_table "products", :force => true do |t|
What can be written like this with the regular calls to column:
in a single statement.
They use the type as the method name instead of as a parameter and allow for multiple columns to be defined
Instead of calling +column+ directly, you can also work with the short-hand definitions for the default types.
== Short-hand examples
# => foo polygon
td.column(:foo, 'polygon')
# Defines a column with a database-specific type.
# => huge_integer DECIMAL(30)
td.column(:huge_integer, :decimal, :precision => 30)
# probably wouldn't hurt to include it.
# While :scale defaults to zero on most databases, it
# => sensor_reading DECIMAL(30,20)
td.column(:sensor_reading, :decimal, :precision => 30, :scale => 20)
# => bill_gates_money DECIMAL(15,2)
td.column(:bill_gates_money, :decimal, :precision => 15, :scale => 2)
# => sales_stage VARCHAR(20) DEFAULT 'new' NOT NULL
td.column(:sales_stage, :string, :limit => 20, :default => 'new', :null => false)
# => picture BLOB(2097152)
td.column(:picture, :binary, :limit => 2.megabytes)
# granted BOOLEAN
td.column(:granted, :boolean)
# Assuming td is an instance of TableDefinition
== Examples
This method returns self.
* OpenBase?: Documentation unclear. Claims storage in double.
Default (38,0).
* Sybase: :precision [1..38], :scale [0..38].
Default (38,0).
* SqlServer?: :precision [1..38], :scale [0..38].
NUMERIC is 19, and DECIMAL is 38.
Default (38,0). WARNING Max :precision/:scale for
* FrontBase?: :precision [1..38], :scale [0..38].
storage rules, decimal being better.
Default (9,0). Internal types NUMERIC and DECIMAL have different
* Firebird: :precision [1..18], :scale [0..18].
Default unknown.
* DB2: :precision [1..63], :scale [0..62].
Default is (38,0).
* Oracle: :precision [1..38], :scale [-84..127].
but the maximum supported :precision is 16. No default.
* SQLite3: No restrictions on :precision and :scale,
Internal storage as strings. No default.
* SQLite2: Any :precision and :scale may be used.
:scale [0..infinity]. No default.
* PostgreSQL: :precision [1..infinity],
Default is (10,0).
* MySQL: :precision [1..63], :scale [0..30].
:precision.
:precision, and makes no comments about the requirements of
* The SQL standard says the default scale should be 0, :scale <=
:decimal columns:
Please be aware of different RDBMS implementations behavior with
range from -999.99 to 999.99.
and a scale of 2. A decimal with a precision of 5 and a scale of 2 can
the decimal point. For example, the number 123.45 has a precision of 5
while the scale is the number of digits that can be stored following
For clarity's sake: the precision is the number of significant digits,
Specifies the scale for a :decimal column.
* :scale -
Specifies the precision for a :decimal column.
* :precision -
have been named :null_allowed.
Allows or disallows +NULL+ values in the column. This option could
* :null -
The column's default value. Use nil for NULL.
* :default -
Requests a maximum column length. This is number of characters for :string and :text columns and number of bytes for :binary and :integer columns.
* :limit -
Available options are (none of these exists by default):
agnostic and should usually be avoided.
database (for example, "polygon" in MySQL), but this will not be database
You may use a type not in this list as long as it is supported by your
:date, :binary, :boolean.
:datetime, :timestamp, :time,
:integer, :float, :decimal,
:primary_key, :string, :text,
which is one of the following:
The +type+ parameter is normally one of the migrations native types,
Instantiates a new column for the table.
def column(name, type, options = {}) column = self[name] || ColumnDefinition.new(@base, name, type) if options[:limit] column.limit = options[:limit] elsif native[type.to_sym].is_a?(Hash) column.limit = native[type.to_sym][:limit] end column.precision = options[:precision] column.scale = options[:scale] column.default = options[:default] column.null = options[:null] @columns << column unless @columns.include? column self end
def initialize(base)
def initialize(base) @columns = [] @base = base end
def method_missing(symbol, *args)
def method_missing(symbol, *args) if symbol.to_s == 'xml' xml_column_fallback(args) end end
def native
def native @base.native_database_types end
def primary_key(name)
Appends a primary key definition to the table definition.
def primary_key(name) column(name, :primary_key) end
def references(*args)
def references(*args) options = args.extract_options! polymorphic = options.delete(:polymorphic) args.each do |col| column("#{col}_id", :integer, options) column("#{col}_type", :string, polymorphic.is_a?(Hash) ? polymorphic : options) unless polymorphic.nil? end end
def timestamps(*args)
Appends :datetime columns :created_at and
def timestamps(*args) options = args.extract_options! column(:created_at, :datetime, options) column(:updated_at, :datetime, options) end
def to_sql
concatenated together. This string can then be prepended and appended to
Returns a String whose contents are the column definitions
def to_sql @columns.map(&:to_sql) * ', ' end
def xml(*args)
def xml(*args) options = args.extract_options! column(args[0], 'xml', options) end
def xml_column_fallback(*args)
def xml_column_fallback(*args) case @base.adapter_name.downcase when 'sqlite', 'mysql' options = args.extract_options! column(args[0], :text, options) end end