Skip to content

Instantly share code, notes, and snippets.

@aisipos
Last active August 26, 2019 01:31
Show Gist options
  • Save aisipos/1464b6fa05272bc70113 to your computer and use it in GitHub Desktop.
Save aisipos/1464b6fa05272bc70113 to your computer and use it in GitHub Desktop.
Patch Rails ActiveRecord Migrations to output migration scripts
namespace :db do
[ :migrate, :rollback ].each do |n|
namespace n do |migration_task|
original_task = migration_task.instance_variable_get("@scope").to_a.reverse.join ":"
[:with_sql, :to_sql ].each do |t|
desc "Run migration, and generated SQL" if t == :with_sql
desc "Generate migration SQL" if t == :to_sql
task t => :environment do |sql_task|
case original_task
when "db:migrate"
filename = 'upgrade.sql'
when "db:rollback"
filename = 'rollback.sql'
else
raise "unkown migration type #{original_task}"
end
ActiveRecord::Base.connection.class.class_eval do
# alias the adapter's execute for later use
alias :old_execute :execute
SQL_FILENAME = filename
RUN_SQL = sql_task.name.ends_with?("with_sql")
# define our own execute
def execute(sql, name = nil)
# check for some DDL and DML statements
if /^(create|alter|drop|insert|delete|update)/i.match sql
File.open(SQL_FILENAME, 'a') { |f| f.puts "#{sql};\n" }
old_execute sql, name if RUN_SQL
else
# pass everything else to the aliased execute
old_execute sql, name
end
end
end
# create or delete content of migration.sql
File.open(SQL_FILENAME, 'w') { |f| f.puts "-- Script created @ #{Time.now}" }
# invoke the normal migration procedure now
Rake::Task[original_task].invoke
puts "Ran #{original_task} and wrote sql to #{filename}"
end
end
end
end
end
@aisipos
Copy link
Author

aisipos commented Jun 16, 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment