I find myself having to execute very similar sql statements (with maybe 1 param besides the table name) on several tables on a rails app. As a result, I'm getting lots of similarly looking migrations, like this one:
class DoSomeSQLOnUser < ActiveRecord::Migration
def up
execute('some long sql that alters the user.field1')
execute('some long sql that alters the user.field2')
end
def down
execute('some sql that undoes the changes')
end
end
Then I have the same thing for clients, sales, etc.
I would like to extend ActiveRecord::Migration
so that I can do this instead:
class DoSomeSQLOnUser < ActiveRecord::Migration
def change
do_custom_thing_on :users, :field1
do_custom_thing_on :users, :field2
end
end
How can I do that? I think I know how to do it when the operations are separated into up and down, like this:
class DoSomeSQLOnUser < ActiveRecord::Migration
def up
do_custom_thing_on :users, :field1
do_custom_thing_on :users, :field2
end
def down
undo_custom_thing_on :users, :field1
undo_custom_thing_on :users, :field2
end
end
But doing it so that the change is "reversible" escapes me.
It doesn't seem to be a official supported way to do this, so probably you'll need to open the class ActiveRecord::Migration::CommandRecorder
and record the new method and its inverted version.
Find the definition of the class at activerecord/lib/active_record/migration/command_recorder.rb.
In Rails 4 there is a reversible helper method, which you can use like this:
def change
do_custom_thing_on :users, :field1
do_custom_thing_on :users, :field2
end
def do_custom_thing_on(table, field)
reversible do |dir|
dir.up { execute "some long sql to alter #{field} on #{table}"}
dir.down { execute "some long sql to undo #{field} on #{table}"}
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With