class ActiveRecord::Migration::ColumnsTest

Public Instance Methods

test_add_rename() click to toggle source

FIXME: this is more of an integration test with AR::Base and the schema modifications. Maybe we should move this?

# File activerecord/test/cases/migration/columns_test.rb, line 14
def test_add_rename
  add_column "test_models", "girlfriend", :string
  TestModel.reset_column_information

  TestModel.create girlfriend: "bobette"

  rename_column "test_models", "girlfriend", "exgirlfriend"

  TestModel.reset_column_information
  bob = TestModel.first

  assert_equal "bobette", bob.exgirlfriend
end
test_change_column() click to toggle source
# File activerecord/test/cases/migration/columns_test.rb, line 185
def test_change_column
  add_column "test_models", "age", :integer
  add_column "test_models", "approved", :boolean, default: true

  old_columns = connection.columns(TestModel.table_name)

  assert old_columns.find { |c| c.name == "age" && c.type == :integer }

  change_column "test_models", "age", :string

  new_columns = connection.columns(TestModel.table_name)

  assert_not new_columns.find { |c| c.name == "age" && c.type == :integer }
  assert new_columns.find { |c| c.name == "age" && c.type == :string }

  old_columns = connection.columns(TestModel.table_name)
  assert old_columns.find { |c|
    default = connection.lookup_cast_type_from_column(c).deserialize(c.default)
    c.name == "approved" && c.type == :boolean && default == true
  }

  change_column :test_models, :approved, :boolean, default: false
  new_columns = connection.columns(TestModel.table_name)

  assert_not new_columns.find { |c|
    default = connection.lookup_cast_type_from_column(c).deserialize(c.default)
    c.name == "approved" && c.type == :boolean && default == true
  }
  assert new_columns.find { |c|
    default = connection.lookup_cast_type_from_column(c).deserialize(c.default)
    c.name == "approved" && c.type == :boolean && default == false
  }
  change_column :test_models, :approved, :boolean, default: true
end
test_change_column_default() click to toggle source
# File activerecord/test/cases/migration/columns_test.rb, line 270
def test_change_column_default
  add_column "test_models", "first_name", :string
  connection.change_column_default "test_models", "first_name", "Tester"

  assert_equal "Tester", TestModel.new.first_name
end
test_change_column_default_to_null() click to toggle source
# File activerecord/test/cases/migration/columns_test.rb, line 277
def test_change_column_default_to_null
  add_column "test_models", "first_name", :string
  connection.change_column_default "test_models", "first_name", nil
  assert_nil TestModel.new.first_name
end
test_change_column_default_with_from_and_to() click to toggle source
# File activerecord/test/cases/migration/columns_test.rb, line 283
def test_change_column_default_with_from_and_to
  add_column "test_models", "first_name", :string
  connection.change_column_default "test_models", "first_name", from: nil, to: "Tester"

  assert_equal "Tester", TestModel.new.first_name
end
test_change_column_nullability() click to toggle source
# File activerecord/test/cases/migration/columns_test.rb, line 171
def test_change_column_nullability
  add_column "test_models", "funny", :boolean
  assert TestModel.columns_hash["funny"].null, "Column 'funny' must initially allow nulls"

  change_column "test_models", "funny", :boolean, null: false, default: true

  TestModel.reset_column_information
  assert_not TestModel.columns_hash["funny"].null, "Column 'funny' must *not* allow nulls at this point"

  change_column "test_models", "funny", :boolean, null: true
  TestModel.reset_column_information
  assert TestModel.columns_hash["funny"].null, "Column 'funny' must allow nulls again at this point"
end
test_change_column_to_drop_default_with_null_false() click to toggle source
# File activerecord/test/cases/migration/columns_test.rb, line 230
def test_change_column_to_drop_default_with_null_false
  add_column "test_models", "contributor", :boolean, default: true, null: false
  assert TestModel.new.contributor?

  change_column "test_models", "contributor", :boolean, default: nil, null: false
  TestModel.reset_column_information
  assert_not TestModel.new.contributor?
  assert_nil TestModel.new.contributor
end
test_change_column_with_custom_index_name() click to toggle source
# File activerecord/test/cases/migration/columns_test.rb, line 249
def test_change_column_with_custom_index_name
  add_column "test_models", "category", :string
  add_index :test_models, :category, name: "test_models_categories_idx"

  assert_equal ["test_models_categories_idx"], connection.indexes("test_models").map(&:name)
  change_column "test_models", "category", :string, null: false, default: "article"

  assert_equal ["test_models_categories_idx"], connection.indexes("test_models").map(&:name)
end
test_change_column_with_long_index_name() click to toggle source
# File activerecord/test/cases/migration/columns_test.rb, line 259
def test_change_column_with_long_index_name
  table_name_prefix = "test_models_"
  long_index_name = table_name_prefix + ("x" * (connection.allowed_index_name_length - table_name_prefix.length))
  add_column "test_models", "category", :string
  add_index :test_models, :category, name: long_index_name

  change_column "test_models", "category", :string, null: false, default: "article"

  assert_equal [long_index_name], connection.indexes("test_models").map(&:name)
end
test_change_column_with_new_default() click to toggle source
# File activerecord/test/cases/migration/columns_test.rb, line 240
def test_change_column_with_new_default
  add_column "test_models", "administrator", :boolean, default: true
  assert TestModel.new.administrator?

  change_column "test_models", "administrator", :boolean, default: false
  TestModel.reset_column_information
  assert_not TestModel.new.administrator?
end
test_change_column_with_nil_default() click to toggle source
# File activerecord/test/cases/migration/columns_test.rb, line 220
def test_change_column_with_nil_default
  add_column "test_models", "contributor", :boolean, default: true
  assert TestModel.new.contributor?

  change_column "test_models", "contributor", :boolean, default: nil
  TestModel.reset_column_information
  assert_not TestModel.new.contributor?
  assert_nil TestModel.new.contributor
end
test_change_type_of_not_null_column() click to toggle source
# File activerecord/test/cases/migration/columns_test.rb, line 161
def test_change_type_of_not_null_column
  change_column "test_models", "updated_at", :datetime, null: false
  change_column "test_models", "updated_at", :datetime, null: false

  TestModel.reset_column_information
  assert_equal false, TestModel.columns_hash["updated_at"].null
ensure
  change_column "test_models", "updated_at", :datetime, null: true
end
test_column_with_index() click to toggle source
# File activerecord/test/cases/migration/columns_test.rb, line 308
def test_column_with_index
  connection.create_table "my_table", force: true do |t|
    t.string :item_number, index: true
  end

  assert connection.index_exists?("my_table", :item_number, name: :index_my_table_on_item_number)
ensure
  connection.drop_table(:my_table) rescue nil
end
test_mysql_rename_column_preserves_auto_increment() click to toggle source
# File activerecord/test/cases/migration/columns_test.rb, line 68
def test_mysql_rename_column_preserves_auto_increment
  rename_column "test_models", "id", "id_test"
  assert connection.columns("test_models").find { |c| c.name == "id_test" }.auto_increment?
  TestModel.reset_column_information
ensure
  rename_column "test_models", "id_test", "id"
end
test_remove_column_no_second_parameter_raises_exception() click to toggle source
# File activerecord/test/cases/migration/columns_test.rb, line 290
def test_remove_column_no_second_parameter_raises_exception
  assert_raise(ArgumentError) { connection.remove_column("funny") }
end
test_remove_column_with_index() click to toggle source
# File activerecord/test/cases/migration/columns_test.rb, line 135
def test_remove_column_with_index
  add_column "test_models", :hat_name, :string
  add_index :test_models, :hat_name

  assert_equal 1, connection.indexes("test_models").size
  remove_column("test_models", "hat_name")
  assert_equal 0, connection.indexes("test_models").size
end
test_remove_column_with_multi_column_index() click to toggle source
# File activerecord/test/cases/migration/columns_test.rb, line 144
def test_remove_column_with_multi_column_index
  add_column "test_models", :hat_size, :integer
  add_column "test_models", :hat_style, :string, limit: 100
  add_index "test_models", ["hat_style", "hat_size"], unique: true

  assert_equal 1, connection.indexes("test_models").size
  remove_column("test_models", "hat_size")

  # Every database and/or database adapter has their own behavior
  # if it drops the multi-column index when any of the indexed columns dropped by remove_column.
  if current_adapter?(:PostgreSQLAdapter, :OracleAdapter)
    assert_equal [], connection.indexes("test_models").map(&:name)
  else
    assert_equal ["index_test_models_on_hat_style_and_hat_size"], connection.indexes("test_models").map(&:name)
  end
end
test_removing_and_renaming_column_preserves_custom_primary_key() click to toggle source
# File activerecord/test/cases/migration/columns_test.rb, line 294
def test_removing_and_renaming_column_preserves_custom_primary_key
  connection.create_table "my_table", primary_key: "my_table_id", force: true do |t|
    t.integer "col_one"
    t.string "col_two", limit: 128, null: false
  end

  remove_column("my_table", "col_two")
  rename_column("my_table", "col_one", "col_three")

  assert_equal "my_table_id", connection.primary_key("my_table")
ensure
  connection.drop_table(:my_table) rescue nil
end
test_rename_column() click to toggle source

FIXME: another integration test. We should decouple this from the AR::Base implementation.

# File activerecord/test/cases/migration/columns_test.rb, line 43
def test_rename_column
  add_column "test_models", "first_name", "string"

  TestModel.create first_name: "foo"

  rename_column "test_models", "first_name", "nick_name"
  TestModel.reset_column_information
  assert_includes TestModel.column_names, "nick_name"
  assert_equal ["foo"], TestModel.all.map(&:nick_name)
end
test_rename_column_does_not_rename_custom_named_index() click to toggle source
# File activerecord/test/cases/migration/columns_test.rb, line 126
def test_rename_column_does_not_rename_custom_named_index
  add_column "test_models", :hat_name, :string
  add_index :test_models, :hat_name, name: "idx_hat_name"

  assert_equal 1, connection.indexes("test_models").size
  rename_column "test_models", "hat_name", "name"
  assert_equal ["idx_hat_name"], connection.indexes("test_models").map(&:name)
end
test_rename_column_preserves_default_value_not_null() click to toggle source
# File activerecord/test/cases/migration/columns_test.rb, line 54
def test_rename_column_preserves_default_value_not_null
  add_column "test_models", "salary", :integer, default: 70000

  default_before = connection.columns("test_models").find { |c| c.name == "salary" }.default
  assert_equal "70000", default_before

  rename_column "test_models", "salary", "annual_salary"

  assert_includes TestModel.column_names, "annual_salary"
  default_after = connection.columns("test_models").find { |c| c.name == "annual_salary" }.default
  assert_equal "70000", default_after
end
test_rename_column_using_symbol_arguments() click to toggle source

FIXME: another integration test. We should decouple this from the AR::Base implementation.

# File activerecord/test/cases/migration/columns_test.rb, line 30
def test_rename_column_using_symbol_arguments
  add_column :test_models, :first_name, :string

  TestModel.create first_name: "foo"

  rename_column :test_models, :first_name, :nick_name
  TestModel.reset_column_information
  assert_includes TestModel.column_names, "nick_name"
  assert_equal ["foo"], TestModel.all.map(&:nick_name)
end
test_rename_column_with_an_index() click to toggle source
# File activerecord/test/cases/migration/columns_test.rb, line 96
def test_rename_column_with_an_index
  add_column "test_models", :hat_name, :string
  add_index :test_models, :hat_name

  assert_equal 1, connection.indexes("test_models").size
  rename_column "test_models", "hat_name", "name"

  assert_equal ["index_test_models_on_name"], connection.indexes("test_models").map(&:name)
end
test_rename_column_with_multi_column_index() click to toggle source
# File activerecord/test/cases/migration/columns_test.rb, line 106
def test_rename_column_with_multi_column_index
  add_column "test_models", :hat_size, :integer
  add_column "test_models", :hat_style, :string, limit: 100
  add_index "test_models", ["hat_style", "hat_size"], unique: true

  rename_column "test_models", "hat_size", "size"
  if current_adapter? :OracleAdapter
    assert_equal ["i_test_models_hat_style_size"], connection.indexes("test_models").map(&:name)
  else
    assert_equal ["index_test_models_on_hat_style_and_size"], connection.indexes("test_models").map(&:name)
  end

  rename_column "test_models", "hat_style", "style"
  if current_adapter? :OracleAdapter
    assert_equal ["i_test_models_style_size"], connection.indexes("test_models").map(&:name)
  else
    assert_equal ["index_test_models_on_style_and_size"], connection.indexes("test_models").map(&:name)
  end
end
test_rename_column_with_sql_reserved_word() click to toggle source
# File activerecord/test/cases/migration/columns_test.rb, line 89
def test_rename_column_with_sql_reserved_word
  add_column "test_models", "first_name", :string
  rename_column "test_models", "first_name", "group"

  assert_includes TestModel.column_names, "group"
end
test_rename_nonexistent_column() click to toggle source
# File activerecord/test/cases/migration/columns_test.rb, line 77
def test_rename_nonexistent_column
  exception = if current_adapter?(:PostgreSQLAdapter, :OracleAdapter)
    ActiveRecord::StatementInvalid
  else
    ActiveRecord::ActiveRecordError
  end

  assert_raise(exception) do
    rename_column "test_models", "nonexistent", "should_fail"
  end
end