Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add support for Mysql column positioning via #add_column and #change_…

…column

add_column and change_column in the Mysql adapter now accept some
additional options:
:first => true        # Put the column in front of all the columns
:after => column_name # Put the colmn after 'column_name'

add_column :new_col, :string, :first => true
add_column :another_col, :integer, :default => 0, :after => :new_col

[#3286 state:committed]

Signed-off-by: Jeremy Kemper <jeremy@bitsweat.net>
  • Loading branch information...
commit ccb197b2e6c2e773f908d3b00f5debe57c22311a 1 parent c253d7b
@bmarini bmarini authored jeremy committed
View
2  activerecord/CHANGELOG
@@ -1,5 +1,7 @@
*2.3.6 (pending)*
+* MySQL: add_ and change_column support positioning. #3286 [Ben Marini]
+
* Reset your Active Record counter caches with the reset_counter_cache class method. #1211 [Mike Breen]
View
15 activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
@@ -480,6 +480,13 @@ def rename_table(table_name, new_name)
execute "RENAME TABLE #{quote_table_name(table_name)} TO #{quote_table_name(new_name)}"
end
+ def add_column(table_name, column_name, type, options = {})
+ add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ADD #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
+ add_column_options!(add_column_sql, options)
+ add_column_position!(add_column_sql, options)
+ execute(add_column_sql)
+ end
+
def change_column_default(table_name, column_name, default) #:nodoc:
column = column_for(table_name, column_name)
change_column table_name, column_name, column.sql_type, :default => default
@@ -508,6 +515,7 @@ def change_column(table_name, column_name, type, options = {}) #:nodoc:
change_column_sql = "ALTER TABLE #{quote_table_name(table_name)} CHANGE #{quote_column_name(column_name)} #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
add_column_options!(change_column_sql, options)
+ add_column_position!(change_column_sql, options)
execute(change_column_sql)
end
@@ -539,6 +547,13 @@ def type_to_sql(type, limit = nil, precision = nil, scale = nil)
end
end
+ def add_column_position!(sql, options)
+ if options[:first]
+ sql << " FIRST"
+ elsif options[:after]
+ sql << " AFTER #{quote_column_name(options[:after])}"
+ end
+ end
# SHOW VARIABLES LIKE 'name'
def show_variable(name)
View
47 activerecord/test/cases/migration_test.rb
@@ -516,6 +516,53 @@ def test_add_remove_single_field_using_symbol_arguments
assert !Person.column_methods_hash.include?(:last_name)
end
+ if current_adapter?(:MysqlAdapter)
+ def testing_table_for_positioning
+ Person.connection.create_table :testings, :id => false do |t|
+ t.column :first, :integer
+ t.column :second, :integer
+ t.column :third, :integer
+ end
+
+ yield Person.connection
+ ensure
+ Person.connection.drop_table :testings rescue nil
+ end
+ protected :testing_table_for_positioning
+
+ def test_column_positioning
+ testing_table_for_positioning do |conn|
+ assert_equal %w(first second third), conn.columns(:testings).map {|c| c.name }
+ end
+ end
+
+ def test_add_column_with_positioning
+ testing_table_for_positioning do |conn|
+ conn.add_column :testings, :new_col, :integer
+ assert_equal %w(first second third new_col), conn.columns(:testings).map {|c| c.name }
+ end
+ testing_table_for_positioning do |conn|
+ conn.add_column :testings, :new_col, :integer, :first => true
+ assert_equal %w(new_col first second third), conn.columns(:testings).map {|c| c.name }
+ end
+ testing_table_for_positioning do |conn|
+ conn.add_column :testings, :new_col, :integer, :after => :first
+ assert_equal %w(first new_col second third), conn.columns(:testings).map {|c| c.name }
+ end
+ end
+
+ def test_change_column_with_positioning
+ testing_table_for_positioning do |conn|
+ conn.change_column :testings, :second, :integer, :first => true
+ assert_equal %w(second first third), conn.columns(:testings).map {|c| c.name }
+ end
+ testing_table_for_positioning do |conn|
+ conn.change_column :testings, :second, :integer, :after => :third
+ assert_equal %w(first third second), conn.columns(:testings).map {|c| c.name }
+ end
+ end
+ end
+
def test_add_rename
Person.delete_all
Please sign in to comment.
Something went wrong with that request. Please try again.