-
Notifications
You must be signed in to change notification settings - Fork 1
Migration DSL
Migration DSL allows you to describe the operations that modify your database in conditional migrations.
#create_table
expects a name of the created table and a block identical to the one
you would pass to a table description
in the declarative schema definition.
You can specify fields, indexes, check constraints and foreign keys here.
migrator.create_table :posts do |t|
t.serial :id, primary_key: true
t.varchar :title, null: false
t.text :body
end
#drop_table
just takes a deleted table's name:
migrator.drop_table :posts
#rename_table
takes both old and new names of the table:
migrator.rename_table :people, to: :users
#alter_table
takes a table's name and a block describing the operations
(not definitions) that have to be run on that table.
migrator.alter_table :users do |t|
# operations with the :users table
end
#add_column
takes a column name, it's type and additional options (similar to the
options in the column's definition):
migrator.alter_table :people do |t|
t.add_column :email, :varchar, null: false
end
#drop_column
just takes the column's name:
migrator.alter_table :people do |t|
t.drop_column :name
end
#rename_column
takes old and new names of the column:
migrator.alter_table :people do |t|
t.rename_column :name, to: :first_name
end
#alter_column_type
takes the column's name and it's new type:
migrator.alter_table :people do |t|
t.alter_column_type :name, :text
end
Changing a column's type from/to one of the PostgreSQL serial types is not supported.
#alter_column_type
allows you to specify how to convert the existing
data to the new type (it translates to the USING
SQL clause):
migrator.alter_table :messages do |t|
t.alter_column_type :read, :boolean, using: 'read::boolean'
end
This is the only way to change column type with a USING
clause; you can't
do that with a declarative schema definition.
#allow_null
removes the NOT NULL
constraint from the column;
it takes the column's name:
migrator.alter_table :people do |t|
t.allow_null :name
end
#disallow_null
adds the NOT NULL
constraint to the column;
it also expects just the column's name:
migrator.alter_table :people do |t|
t.disallow_null :created_at
end
#alter_column_default
changes the column's default value;
it takes the column's name and a new default (just like in declarative
definition,
you can pass strings, fixnums, floats, true
& false
,
dates, times and symbols - the latter are interpreted as raw SQL):
migrator.alter_table :people do |t|
t.alter_column_default :created_at, :'now()'
end
#add_primary_key
creates a primary key on the specified columns. It does not
create the actual columns, they must already exist in that table.
migrator.alter_table :people do |t|
t.add_primary_key :id
end
#drop_primary_key
is called without any arguments; it drops the primary key
from that table.
migrator.alter_table :people do |t|
t.drop_primary_key
end
#add_index
expects the same arguments and options as the #index
method
in the schema definition:
you can pass one or several column names (as symbols)
and/or expressions (as strings) and optionally specify index name, uniqueness,
type, condition (for partial indexes) and columns ordering:
migrator.alter_table :users do |t|
t.add_index :email, unique: true
end
#drop_index
expects just the name of the index:
migrator.alter_table :people do |t|
t.drop_index :people_phone_index
end
#add_check
adds a check constraint; it takes the name of the constraint
and a condition as an SQL string:
migrator.alter_table :people do |t|
t.add_check :name_length, 'character_length(name::text) > 4'
end
#drop_check
drops a check constraint; it expects just the constraint's name:
migrator.alter_table :people do |t|
t.drop_check :phone_format
end
#add_foreign_key
creates a foreign key; it expects the same arguments as
the #foreign_key
method in the schema definition -
referencing fields, referenced table, optionally referenced fields,
on_update
/on_delete
actions and the deferrable
option:
migrator.alter_table :posts do |t|
t.add_foreign_key :person_id, references: :people
end
#drop_foreign_key
just takes the name of the foreign key:
migrator.alter_table :posts do |t|
t.drop_foreign_key :posts_person_id_fkey
end
#create_enum
creates an enum datatype; it expects a type's name
and an array of possible values:
migrator.create_enum :user_role, [:guest, :user, :admin]
#drop_enum
takes just the type's name:
migrator.drop_enum :user_role
#rename_enum
takes old and new names of the type:
migrator.rename_enum :user_role, to: :role
#create_extension
enables a given extension: it takes the name
of the extension:
migrator.create_extension :hstore
#drop_extension
disables the extension with a given name:
migrator.drop_extension :hstore
The #execute
method allows you to run any SQL statement:
migrator.execute "UPDATE messages SET read = 't'"