Written by Sean Behan on Sun Jun 17th 2012

I'm a big fan of the yaml_db plugin. But I don't like running rake db:data:load, only to find that my db columns mismatch my model attributes, thus aborting the data import task. To quickly add/remove columns/attributes from a model and rebuild the database with previous db info, I wrote this simple rake task. It saves model records as yaml in db/seandb.yml, and reloads them in the same task but with the db rebuilt. I nest the save method in begin/rescue so that if there are any conflicts the task will continue.

This biggest challenge was to get a list of all the active record models in the Rails app. This problem has been posted a lot and I didn't find an easy solution. For now, I just look in the app/models directory and 'classify' and 'constantize' the file name. This will load the model so that I can iterate over all the active record subclasses and call the appropriate Model.find(:all) method. I could maybe do the same w/ all files in the Rails.configuration.load_paths, but my models are, at least for now, under app/models. Plugin models are loaded and available from the rake task if you require the :environment.

It's as simple as running

rake db:everything
SAVEDB = "#{RAILS_ROOT}/db/seandb.yml"
namespace :db do
   task :everything => [:environment, :spit, :drop, :create, :migrate, :populate] do
     desc "spit out model records as yaml, rebuild the database and repopulate the db"

task :spit do Dir["#{RAILS_ROOT}/app/models/"].each {|file| (File.basename(file,".").classify.constantize)} File.open(SAVEDB, "w") do |f| ActiveRecord::Base.send(:subclasses).each do |model| begin model.find(:all).each do |record| f.write(record.to_yaml) print "\twrote #{record.class}\n" end rescue end end end end

task :populate do File.open( SAVEDB ) do |yf| YAML.each_document( yf ) do |ydoc| begin m = ydoc.clone m.save p "...saved #{m.id}" rescue end end end end end

Tagged with..
#active record #rake #tasks #yaml #yaml_db #Ruby on Rails

Just finishing up brewing up some fresh ground comments...