I like to keep database columns in a reasonably logical order. I generally keep primary keys as the first column, then content columns, then special usage columns, then foreign keys:
id
name
description
created_on
updated_on
account_id
Now, say I added a slug
column with a migration:
def self.up
add_column "projects", "slug", :string
end
That’s fine, I have my new column but it’s after my foreign keys:
id
name
description
created_on
updated_on
account_id
slug
What’s it doing down there? I want it after the name
column! Wouldn’t it be nice if you could specify an :after
option for add_column
.
We can make this possible by monkey patching the add_column
method at the top of our migration file:
module ActiveRecord
module ConnectionAdapters # :nodoc:
module SchemaStatements
def add_column(table_name, column_name, type, options = {})
add_column_sql = "ALTER TABLE #{table_name} ADD #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
after_column = options.delete(:after)
add_column_options!(add_column_sql, options)
add_column_sql << " AFTER #{after_column}" if after_column
execute(add_column_sql)
end
end
end
end
This lets us do the following:
def self.up
add_column "projects", "slug", :string, :after => 'name'
end
Which gives us:
id
name
slug
description
created_on
updated_on
account_id
Much better. This may seem a little petty, however as your tables get more and more columns it makes things much easier to follow.
Please note: I have only tested this with MySQL.