Specifying Column Order in ActiveRecord Migrations
ActiveRecord migrations don't allow you to control column order when adding or changing columns. You can always just
execute "ALTER TABLE ..." # but it's ugly and hard to remember the details.
If you're willing to give up vendor neutrality, you can have the feature in pretty-Ruby-migration syntax with a small effort. Here's an implementation for MySQL that adds options :first
and :after
to add_column
and change_column
.
ActiveRecord::ConnectionAdapters::MysqlAdapter.class_eval do
super
if options[:after]
sql << " AFTER "
elsif options[:first]
sql << " FIRST"
end
end
end
(It's also available in this gist if you'd like to suggest a cleaner way.)
With that in place,
a.add_column :foos, :bar, :string, :after => :baz
will execute
`foos` ADD `bar` varchar(255) AFTER `baz`
and
a.add_column :foos, :bar, :string, :first => true
will execute
`foos` ADD `bar` varchar(255) FIRST
Love that Ruby!
Now this is a monkey-patch, but as monkey-patches go it's pretty innocuous. Rather than redefining a method that's already implemented in MysqlAdapter (and as with many monkey-patches copy-pasting the existing implementation so we can modify it), we're defining a new override of a method (albeit undocumented) inherited from the SchemaStatements module (via AbstractAdapter). If you wanted to, you could subclass MysqlAdapter and then configure Rails to use your own adapter, but I suspect that would be more expensive to own than just adding this method to MysqlAdapter. (Beware: there are many useful Rails-provided rake tasks that look at your adapter string to decide whether to be useful or to spit in your face.)
No comments:
Post a Comment