Skip to content

Instantly share code, notes, and snippets.

@jasantunes
Last active July 18, 2017 20:41
Show Gist options
  • Save jasantunes/f1cecc87ad5901c7743b0b09c51817ef to your computer and use it in GitHub Desktop.
Save jasantunes/f1cecc87ad5901c7743b0b09c51817ef to your computer and use it in GitHub Desktop.
Run schema migrations and seeds migrations in chronological order
# lib/tasks/db.rake
require_relative 'helpers/seed_migration_helper'
namespace :db do
desc 'Run db:migrate and seed:migrate in chronological order'
task(migrate_with_data: :environment) do
schema_migrations = SeedMigrationHelper.schema_migrations
seed_migrations = SeedMigrationHelper.seed_migrations
migrations_to_run = (schema_migrations + seed_migrations).sort_by { |k| k[:version] }
migrations_to_run.each do |migration|
# Let's use deterministic fake data.
srand(migration[:version])
Faker::Config.random = Random.new(migration[:version])
if migration[:schema]
SeedMigrationHelper.schema_migration_up(migration)
else
SeedMigrationHelper.seed_migration_up(migration)
end
end
end
end
# lib/tasks/helpers/seed_migration_helper.rb
module SeedMigrationHelper
class << self
def schema_migration_up(migration)
paths = ActiveRecord::Tasks::DatabaseTasks.migrations_paths
ActiveRecord::Migrator.run(:up, paths, migration[:version])
end
def schema_migrations
schema_migrations_from_active_record
rescue ActiveRecord::StatementInvalid => _ # migrations table doesn't exit yet
schema_migrations_from_filesystem
end
def seed_migration_up(migration)
SeedMigration::Migrator.run_migrations(migration[:filename])
end
def seed_migrations
seed_migrations_from_active_record
rescue ActiveRecord::StatementInvalid => _ # migrations table doesn't exit yet
seed_migrations_from_filesystem
end
private
def schema_migrations_from_active_record
current_version = ActiveRecord::Migrator.current_version
ActiveRecord::Migrator
.get_all_versions
.delete_if { |version| version <= current_version }
.map { |version| { version: version, schema: true } }
end
def schema_migrations_from_filesystem
paths = ActiveRecord::Tasks::DatabaseTasks.migrations_paths
files = Dir.glob(Rails.root.join('db', paths.first).join('*_*.rb').to_s)
migrations_from_filesystem(files, schema: true)
end
def seed_migrations_from_active_record
migrations = []
all_migration_versions = SeedMigration::DataMigration.all.map(&:version)
files = Dir.glob(Rails.root.join('db', SeedMigration.migrations_path).join('*_*.rb').to_s)
files.each do |file|
filename = file.split('/').last
version = filename.split('_').first
migrations << { version: version.to_i, filename: filename, schema: false } unless all_migration_versions.include?(version)
end
migrations
end
def seed_migrations_from_filesystem
files = Dir.glob(Rails.root.join('db', SeedMigration.migrations_path).join('*_*.rb').to_s)
migrations_from_filesystem(files, schema: false)
end
def migrations_from_filesystem(files, schema:)
migrations = []
files.each do |file|
filename = file.split('/').last
version = filename.split('_').first
migrations << { version: version.to_i, filename: filename, schema: schema }
end
migrations
end
end
end
@jasantunes
Copy link
Author

jasantunes commented Jul 14, 2017

Use gem seed_migration with this rake task.

To run schema migrations (db:migrate) and seed migrations (seed:migrate) in chronological order, run this rake task with:

rake db:migrate_with_data

You can also drop the database with:

rake db:drop db:create db:migrate_with_data

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