2017-07-09 13:41:28 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2012-01-12 14:33:07 -05:00
|
|
|
require "cases/migration/helper"
|
|
|
|
|
|
|
|
module ActiveRecord
|
|
|
|
class Migration
|
2013-02-23 20:26:01 -05:00
|
|
|
class ColumnsTest < ActiveRecord::TestCase
|
2012-01-12 14:33:07 -05:00
|
|
|
include ActiveRecord::Migration::TestHelper
|
|
|
|
|
2015-03-10 22:21:19 -04:00
|
|
|
self.use_transactional_tests = false
|
2012-01-12 14:33:07 -05:00
|
|
|
|
|
|
|
# FIXME: this is more of an integration test with AR::Base and the
|
|
|
|
# schema modifications. Maybe we should move this?
|
|
|
|
def test_add_rename
|
|
|
|
add_column "test_models", "girlfriend", :string
|
|
|
|
TestModel.reset_column_information
|
|
|
|
|
2016-08-06 13:37:57 -04:00
|
|
|
TestModel.create girlfriend: "bobette"
|
2012-01-12 14:33:07 -05:00
|
|
|
|
|
|
|
rename_column "test_models", "girlfriend", "exgirlfriend"
|
|
|
|
|
|
|
|
TestModel.reset_column_information
|
2012-04-26 13:32:55 -04:00
|
|
|
bob = TestModel.first
|
2012-01-12 14:33:07 -05:00
|
|
|
|
|
|
|
assert_equal "bobette", bob.exgirlfriend
|
|
|
|
end
|
|
|
|
|
|
|
|
# FIXME: another integration test. We should decouple this from the
|
|
|
|
# AR::Base implementation.
|
|
|
|
def test_rename_column_using_symbol_arguments
|
|
|
|
add_column :test_models, :first_name, :string
|
|
|
|
|
2016-08-06 13:37:57 -04:00
|
|
|
TestModel.create first_name: "foo"
|
2012-01-12 14:33:07 -05:00
|
|
|
|
|
|
|
rename_column :test_models, :first_name, :nick_name
|
|
|
|
TestModel.reset_column_information
|
2016-09-16 12:44:05 -04:00
|
|
|
assert_includes TestModel.column_names, "nick_name"
|
2016-08-06 12:26:20 -04:00
|
|
|
assert_equal ["foo"], TestModel.all.map(&:nick_name)
|
2012-01-12 14:33:07 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
# FIXME: another integration test. We should decouple this from the
|
|
|
|
# AR::Base implementation.
|
|
|
|
def test_rename_column
|
|
|
|
add_column "test_models", "first_name", "string"
|
|
|
|
|
2016-08-06 13:37:57 -04:00
|
|
|
TestModel.create first_name: "foo"
|
2012-01-12 14:33:07 -05:00
|
|
|
|
|
|
|
rename_column "test_models", "first_name", "nick_name"
|
|
|
|
TestModel.reset_column_information
|
2016-09-16 12:44:05 -04:00
|
|
|
assert_includes TestModel.column_names, "nick_name"
|
2016-08-06 12:26:20 -04:00
|
|
|
assert_equal ["foo"], TestModel.all.map(&:nick_name)
|
2012-01-12 14:33:07 -05:00
|
|
|
end
|
2012-01-12 16:14:58 -05:00
|
|
|
|
|
|
|
def test_rename_column_preserves_default_value_not_null
|
2016-08-06 13:37:57 -04:00
|
|
|
add_column "test_models", "salary", :integer, default: 70000
|
2012-01-12 16:14:58 -05:00
|
|
|
|
|
|
|
default_before = connection.columns("test_models").find { |c| c.name == "salary" }.default
|
2016-08-06 12:26:20 -04:00
|
|
|
assert_equal "70000", default_before
|
2012-01-12 16:14:58 -05:00
|
|
|
|
2013-03-28 12:15:08 -04:00
|
|
|
rename_column "test_models", "salary", "annual_salary"
|
2012-01-12 16:14:58 -05:00
|
|
|
|
2016-09-16 12:44:05 -04:00
|
|
|
assert_includes TestModel.column_names, "annual_salary"
|
2013-03-28 12:15:08 -04:00
|
|
|
default_after = connection.columns("test_models").find { |c| c.name == "annual_salary" }.default
|
2016-08-06 12:26:20 -04:00
|
|
|
assert_equal "70000", default_after
|
2012-01-12 16:14:58 -05:00
|
|
|
end
|
|
|
|
|
2015-12-15 17:01:30 -05:00
|
|
|
if current_adapter?(:Mysql2Adapter)
|
2013-03-25 16:30:53 -04:00
|
|
|
def test_mysql_rename_column_preserves_auto_increment
|
|
|
|
rename_column "test_models", "id", "id_test"
|
2018-01-25 18:14:09 -05:00
|
|
|
assert_predicate connection.columns("test_models").find { |c| c.name == "id_test" }, :auto_increment?
|
2014-08-14 12:27:50 -04:00
|
|
|
TestModel.reset_column_information
|
|
|
|
ensure
|
|
|
|
rename_column "test_models", "id_test", "id"
|
2013-03-25 16:30:53 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-01-12 16:14:58 -05:00
|
|
|
def test_rename_nonexistent_column
|
|
|
|
exception = if current_adapter?(:PostgreSQLAdapter, :OracleAdapter)
|
2016-08-06 13:55:02 -04:00
|
|
|
ActiveRecord::StatementInvalid
|
2016-08-07 17:41:00 -04:00
|
|
|
else
|
|
|
|
ActiveRecord::ActiveRecordError
|
|
|
|
end
|
|
|
|
|
2012-01-12 16:14:58 -05:00
|
|
|
assert_raise(exception) do
|
|
|
|
rename_column "test_models", "nonexistent", "should_fail"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_rename_column_with_sql_reserved_word
|
2016-08-06 12:26:20 -04:00
|
|
|
add_column "test_models", "first_name", :string
|
2012-01-12 16:14:58 -05:00
|
|
|
rename_column "test_models", "first_name", "group"
|
|
|
|
|
2016-09-16 12:44:05 -04:00
|
|
|
assert_includes TestModel.column_names, "group"
|
2012-01-12 16:14:58 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_rename_column_with_an_index
|
|
|
|
add_column "test_models", :hat_name, :string
|
|
|
|
add_index :test_models, :hat_name
|
|
|
|
|
2016-08-06 12:26:20 -04:00
|
|
|
assert_equal 1, connection.indexes("test_models").size
|
2012-01-12 16:14:58 -05:00
|
|
|
rename_column "test_models", "hat_name", "name"
|
2012-12-28 16:56:44 -05:00
|
|
|
|
2016-08-06 12:26:20 -04:00
|
|
|
assert_equal ["index_test_models_on_name"], connection.indexes("test_models").map(&:name)
|
2012-12-28 16:56:44 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
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
|
|
|
|
|
2016-08-06 12:26:20 -04:00
|
|
|
rename_column "test_models", "hat_size", "size"
|
2019-03-02 22:10:36 -05:00
|
|
|
assert_equal ["index_test_models_on_hat_style_and_size"], connection.indexes("test_models").map(&:name)
|
2012-12-28 16:56:44 -05:00
|
|
|
|
2016-08-06 12:26:20 -04:00
|
|
|
rename_column "test_models", "hat_style", "style"
|
2019-03-02 22:10:36 -05:00
|
|
|
assert_equal ["index_test_models_on_style_and_size"], connection.indexes("test_models").map(&:name)
|
2012-12-28 16:56:44 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_rename_column_does_not_rename_custom_named_index
|
|
|
|
add_column "test_models", :hat_name, :string
|
2016-08-06 13:37:57 -04:00
|
|
|
add_index :test_models, :hat_name, name: "idx_hat_name"
|
2012-12-28 16:56:44 -05:00
|
|
|
|
2016-08-06 12:26:20 -04:00
|
|
|
assert_equal 1, connection.indexes("test_models").size
|
2012-12-28 16:56:44 -05:00
|
|
|
rename_column "test_models", "hat_name", "name"
|
2016-08-06 12:26:20 -04:00
|
|
|
assert_equal ["idx_hat_name"], connection.indexes("test_models").map(&:name)
|
2012-01-12 16:14:58 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_remove_column_with_index
|
|
|
|
add_column "test_models", :hat_name, :string
|
|
|
|
add_index :test_models, :hat_name
|
|
|
|
|
2016-08-06 12:26:20 -04:00
|
|
|
assert_equal 1, connection.indexes("test_models").size
|
2012-01-12 17:47:36 -05:00
|
|
|
remove_column("test_models", "hat_name")
|
2016-08-06 12:26:20 -04:00
|
|
|
assert_equal 0, connection.indexes("test_models").size
|
2012-01-12 16:14:58 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_remove_column_with_multi_column_index
|
2017-08-31 11:42:13 -04:00
|
|
|
# MariaDB starting with 10.2.8
|
|
|
|
# Dropping a column that is part of a multi-column UNIQUE constraint is not permitted.
|
2019-03-29 11:18:48 -04:00
|
|
|
skip if current_adapter?(:Mysql2Adapter) && connection.mariadb? && connection.database_version >= "10.2.8"
|
2017-08-31 11:42:13 -04:00
|
|
|
|
2012-01-12 16:14:58 -05:00
|
|
|
add_column "test_models", :hat_size, :integer
|
2016-08-06 13:37:57 -04:00
|
|
|
add_column "test_models", :hat_style, :string, limit: 100
|
|
|
|
add_index "test_models", ["hat_style", "hat_size"], unique: true
|
2012-01-12 16:14:58 -05:00
|
|
|
|
2016-08-06 12:26:20 -04:00
|
|
|
assert_equal 1, connection.indexes("test_models").size
|
2012-01-12 16:14:58 -05:00
|
|
|
remove_column("test_models", "hat_size")
|
2012-12-27 19:46:36 -05:00
|
|
|
|
2013-02-23 09:32:18 -05:00
|
|
|
# Every database and/or database adapter has their own behavior
|
2013-01-01 12:39:18 -05:00
|
|
|
# if it drops the multi-column index when any of the indexed columns dropped by remove_column.
|
|
|
|
if current_adapter?(:PostgreSQLAdapter, :OracleAdapter)
|
2016-08-06 12:26:20 -04:00
|
|
|
assert_equal [], connection.indexes("test_models").map(&:name)
|
2012-12-27 19:46:36 -05:00
|
|
|
else
|
2016-08-06 12:26:20 -04:00
|
|
|
assert_equal ["index_test_models_on_hat_style_and_hat_size"], connection.indexes("test_models").map(&:name)
|
2012-12-27 19:46:36 -05:00
|
|
|
end
|
2012-01-12 16:14:58 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_change_type_of_not_null_column
|
2016-08-06 13:37:57 -04:00
|
|
|
change_column "test_models", "updated_at", :datetime, null: false
|
|
|
|
change_column "test_models", "updated_at", :datetime, null: false
|
2012-12-27 19:46:36 -05:00
|
|
|
|
|
|
|
TestModel.reset_column_information
|
2016-08-06 12:26:20 -04:00
|
|
|
assert_equal false, TestModel.columns_hash["updated_at"].null
|
2012-12-27 19:46:36 -05:00
|
|
|
ensure
|
2016-08-06 13:37:57 -04:00
|
|
|
change_column "test_models", "updated_at", :datetime, null: true
|
2012-01-12 16:14:58 -05:00
|
|
|
end
|
2012-01-12 16:35:09 -05:00
|
|
|
|
|
|
|
def test_change_column_nullability
|
|
|
|
add_column "test_models", "funny", :boolean
|
|
|
|
assert TestModel.columns_hash["funny"].null, "Column 'funny' must initially allow nulls"
|
|
|
|
|
2016-08-06 13:37:57 -04:00
|
|
|
change_column "test_models", "funny", :boolean, null: false, default: true
|
2012-01-12 16:35:09 -05:00
|
|
|
|
|
|
|
TestModel.reset_column_information
|
2012-12-27 19:46:36 -05:00
|
|
|
assert_not TestModel.columns_hash["funny"].null, "Column 'funny' must *not* allow nulls at this point"
|
2012-01-12 16:35:09 -05:00
|
|
|
|
2016-08-06 13:37:57 -04:00
|
|
|
change_column "test_models", "funny", :boolean, null: true
|
2012-01-12 16:35:09 -05:00
|
|
|
TestModel.reset_column_information
|
|
|
|
assert TestModel.columns_hash["funny"].null, "Column 'funny' must allow nulls again at this point"
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_change_column
|
2016-08-06 12:26:20 -04:00
|
|
|
add_column "test_models", "age", :integer
|
2016-08-06 13:37:57 -04:00
|
|
|
add_column "test_models", "approved", :boolean, default: true
|
2012-01-12 16:35:09 -05:00
|
|
|
|
2012-02-02 13:08:31 -05:00
|
|
|
old_columns = connection.columns(TestModel.table_name)
|
2012-01-12 16:35:09 -05:00
|
|
|
|
2016-08-06 12:26:20 -04:00
|
|
|
assert old_columns.find { |c| c.name == "age" && c.type == :integer }
|
2012-01-12 16:35:09 -05:00
|
|
|
|
|
|
|
change_column "test_models", "age", :string
|
|
|
|
|
2012-02-02 13:08:31 -05:00
|
|
|
new_columns = connection.columns(TestModel.table_name)
|
2012-01-12 16:35:09 -05:00
|
|
|
|
2016-09-01 17:41:49 -04:00
|
|
|
assert_not new_columns.find { |c| c.name == "age" && c.type == :integer }
|
|
|
|
assert new_columns.find { |c| c.name == "age" && c.type == :string }
|
2012-01-12 16:35:09 -05:00
|
|
|
|
2012-02-02 13:08:31 -05:00
|
|
|
old_columns = connection.columns(TestModel.table_name)
|
2012-01-12 16:35:09 -05:00
|
|
|
assert old_columns.find { |c|
|
2015-02-17 13:29:51 -05:00
|
|
|
default = connection.lookup_cast_type_from_column(c).deserialize(c.default)
|
2016-08-06 12:26:20 -04:00
|
|
|
c.name == "approved" && c.type == :boolean && default == true
|
2012-01-12 16:35:09 -05:00
|
|
|
}
|
|
|
|
|
2016-08-06 13:37:57 -04:00
|
|
|
change_column :test_models, :approved, :boolean, default: false
|
2012-02-02 13:08:31 -05:00
|
|
|
new_columns = connection.columns(TestModel.table_name)
|
2012-01-12 16:35:09 -05:00
|
|
|
|
2014-06-17 17:39:13 -04:00
|
|
|
assert_not new_columns.find { |c|
|
2015-02-17 13:29:51 -05:00
|
|
|
default = connection.lookup_cast_type_from_column(c).deserialize(c.default)
|
2016-09-01 17:41:49 -04:00
|
|
|
c.name == "approved" && c.type == :boolean && default == true
|
2014-06-17 17:39:13 -04:00
|
|
|
}
|
|
|
|
assert new_columns.find { |c|
|
2015-02-17 13:29:51 -05:00
|
|
|
default = connection.lookup_cast_type_from_column(c).deserialize(c.default)
|
2016-09-01 17:41:49 -04:00
|
|
|
c.name == "approved" && c.type == :boolean && default == false
|
2014-06-17 17:39:13 -04:00
|
|
|
}
|
2016-08-06 13:37:57 -04:00
|
|
|
change_column :test_models, :approved, :boolean, default: true
|
2012-01-12 16:35:09 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_change_column_with_nil_default
|
2016-08-06 13:37:57 -04:00
|
|
|
add_column "test_models", "contributor", :boolean, default: true
|
2018-01-25 18:14:09 -05:00
|
|
|
assert_predicate TestModel.new, :contributor?
|
2012-01-12 16:35:09 -05:00
|
|
|
|
2016-08-06 13:37:57 -04:00
|
|
|
change_column "test_models", "contributor", :boolean, default: nil
|
2012-01-12 16:35:09 -05:00
|
|
|
TestModel.reset_column_information
|
2018-01-25 18:14:09 -05:00
|
|
|
assert_not_predicate TestModel.new, :contributor?
|
2012-01-12 16:35:09 -05:00
|
|
|
assert_nil TestModel.new.contributor
|
|
|
|
end
|
|
|
|
|
Fix `change_column` to drop default with `null: false`
Currently `change_column` cannot drop default if `null: false` is
specified at the same time. This change fixes the issue.
```ruby
# cannot drop default
change_column "tests", "contributor", :boolean, default: nil, null: false
# we need the following workaround currently
change_column "tests", "contributor", :boolean, null: false
change_column "tests", "contributor", :boolean, default: nil
```
Closes #26582
2016-09-22 08:22:14 -04:00
|
|
|
def test_change_column_to_drop_default_with_null_false
|
|
|
|
add_column "test_models", "contributor", :boolean, default: true, null: false
|
2018-01-25 18:14:09 -05:00
|
|
|
assert_predicate TestModel.new, :contributor?
|
Fix `change_column` to drop default with `null: false`
Currently `change_column` cannot drop default if `null: false` is
specified at the same time. This change fixes the issue.
```ruby
# cannot drop default
change_column "tests", "contributor", :boolean, default: nil, null: false
# we need the following workaround currently
change_column "tests", "contributor", :boolean, null: false
change_column "tests", "contributor", :boolean, default: nil
```
Closes #26582
2016-09-22 08:22:14 -04:00
|
|
|
|
|
|
|
change_column "test_models", "contributor", :boolean, default: nil, null: false
|
|
|
|
TestModel.reset_column_information
|
2018-01-25 18:14:09 -05:00
|
|
|
assert_not_predicate TestModel.new, :contributor?
|
Fix `change_column` to drop default with `null: false`
Currently `change_column` cannot drop default if `null: false` is
specified at the same time. This change fixes the issue.
```ruby
# cannot drop default
change_column "tests", "contributor", :boolean, default: nil, null: false
# we need the following workaround currently
change_column "tests", "contributor", :boolean, null: false
change_column "tests", "contributor", :boolean, default: nil
```
Closes #26582
2016-09-22 08:22:14 -04:00
|
|
|
assert_nil TestModel.new.contributor
|
|
|
|
end
|
|
|
|
|
2012-01-12 16:35:09 -05:00
|
|
|
def test_change_column_with_new_default
|
2016-08-06 13:37:57 -04:00
|
|
|
add_column "test_models", "administrator", :boolean, default: true
|
2018-01-25 18:14:09 -05:00
|
|
|
assert_predicate TestModel.new, :administrator?
|
2012-01-12 16:35:09 -05:00
|
|
|
|
2016-08-06 13:37:57 -04:00
|
|
|
change_column "test_models", "administrator", :boolean, default: false
|
2012-01-12 16:35:09 -05:00
|
|
|
TestModel.reset_column_information
|
2018-01-25 18:14:09 -05:00
|
|
|
assert_not_predicate TestModel.new, :administrator?
|
2012-01-12 16:35:09 -05:00
|
|
|
end
|
|
|
|
|
2012-12-15 16:42:22 -05:00
|
|
|
def test_change_column_with_custom_index_name
|
|
|
|
add_column "test_models", "category", :string
|
2016-08-06 12:26:20 -04:00
|
|
|
add_index :test_models, :category, name: "test_models_categories_idx"
|
2012-12-15 16:42:22 -05:00
|
|
|
|
2016-08-06 12:26:20 -04:00
|
|
|
assert_equal ["test_models_categories_idx"], connection.indexes("test_models").map(&:name)
|
|
|
|
change_column "test_models", "category", :string, null: false, default: "article"
|
2012-12-15 16:42:22 -05:00
|
|
|
|
2016-08-06 12:26:20 -04:00
|
|
|
assert_equal ["test_models_categories_idx"], connection.indexes("test_models").map(&:name)
|
2012-12-15 16:42:22 -05:00
|
|
|
end
|
|
|
|
|
2012-12-27 19:27:26 -05:00
|
|
|
def test_change_column_with_long_index_name
|
2016-08-06 12:26:20 -04:00
|
|
|
table_name_prefix = "test_models_"
|
2019-04-20 04:36:22 -04:00
|
|
|
long_index_name = table_name_prefix + ("x" * (connection.index_name_length - table_name_prefix.length))
|
2012-12-27 19:27:26 -05:00
|
|
|
add_column "test_models", "category", :string
|
|
|
|
add_index :test_models, :category, name: long_index_name
|
|
|
|
|
2016-08-06 12:26:20 -04:00
|
|
|
change_column "test_models", "category", :string, null: false, default: "article"
|
2012-12-27 19:27:26 -05:00
|
|
|
|
2016-08-06 12:26:20 -04:00
|
|
|
assert_equal [long_index_name], connection.indexes("test_models").map(&:name)
|
2012-12-27 19:27:26 -05:00
|
|
|
end
|
|
|
|
|
2012-01-12 16:35:09 -05:00
|
|
|
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
|
|
|
|
|
|
|
|
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
|
2015-05-04 16:11:15 -04:00
|
|
|
|
|
|
|
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
|
2012-01-12 18:43:41 -05:00
|
|
|
|
|
|
|
def test_remove_column_no_second_parameter_raises_exception
|
|
|
|
assert_raise(ArgumentError) { connection.remove_column("funny") }
|
|
|
|
end
|
2013-02-23 09:32:18 -05:00
|
|
|
|
|
|
|
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")
|
|
|
|
|
2016-08-06 12:26:20 -04:00
|
|
|
assert_equal "my_table_id", connection.primary_key("my_table")
|
2013-02-23 09:32:18 -05:00
|
|
|
ensure
|
|
|
|
connection.drop_table(:my_table) rescue nil
|
|
|
|
end
|
2014-02-20 12:54:13 -05:00
|
|
|
|
|
|
|
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
|
2019-01-16 09:11:16 -05:00
|
|
|
|
|
|
|
def test_add_column_without_column_name
|
|
|
|
e = assert_raise ArgumentError do
|
|
|
|
connection.create_table "my_table", force: true do |t|
|
|
|
|
t.timestamp
|
|
|
|
end
|
|
|
|
end
|
2019-02-09 18:34:37 -05:00
|
|
|
assert_equal "Missing column name(s) for timestamp", e.message
|
|
|
|
ensure
|
|
|
|
connection.drop_table :my_table, if_exists: true
|
2019-01-16 09:11:16 -05:00
|
|
|
end
|
2012-01-12 14:33:07 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|