As mentioned in our previous posts regarding database migrations in Rails, we have introduced a method of managing seed data in migrations. Although this methodology still has some problems, generally speaking it works pretty well.
After a database migration, a schema dump takes place. This allows fast recreation of databases without having to go through every single migration. The problem with this is that any seed data added during the migrations is not added back in when doing a db:reset
. This can be solved by having a similar function to Schema Dumper.
Here are the seed data tasks (you probably want to add these into the db namespace):
namespace :seed_data do desc 'Load schema seed data' task :load => :environment do puts "== Loading dumped seed data" config = ActiveRecord::Base.configurations[RAILS_ENV || 'development'] ActiveRecord::Base.establish_connection(config) require 'active_record/fixtures' Dir.glob(RAILS_ROOT + '/db/seed_data/global/*.yml').each do |file| Fixtures.create_fixtures(RAILS_ROOT + '/db/seed_data/global', File.basename(file, '.*')) end end desc 'Save schema seed datae' task :dump => :environment do config = ActiveRecord::Base.configurations[RAILS_ENV || 'development'] ActiveRecord::Base.establish_connection(config) Database::SeedDataDumper.dump(ActiveRecord::Base.connection) end end
You’ll need the SeedDataDumper class:
module Database class SeedDataDumper def self.dump(connection) new(connection).dump() true end def dump() @connection.tables.each do |table| if @connection.select_all("DESCRIBE #{table}").inject(false) { |b, col| b || (col["Field"]=="came_from_migration") } data = @connection.select_all("SELECT * FROM #{table} WHERE came_from_migration IS NOT NULL") if !data.empty? outfile = File.new("#{@folder}/#{table}.yml", "w") header(outfile) i = "0" outfile.write data.inject({}) { |hash, record| hash["#{table}_#{i.succ!}"] = record hash }.to_yaml footer(outfile) end end end end private def initialize(connection) @connection = connection @folder = "#{RAILS_ROOT}/db/seed_data" puts "== Dumping seed data" end def header(stream) stream.puts <<HEADER # This file is auto-generated from all the current "came_from_migration" rows in the selected # database. It generates a yaml file per table which can be loaded in again using fixtures. HEADER end def footer(stream) stream end end end [/sourcecode] Remember to put the following line at the end of your <code>db:migrate</code> task: Rake::Task["db:seed_data:dump"].invoke if ActiveRecord::Base.schema_format == :ruby