module AmbitiousSeeder class Railtie < Rails::Railtie rake_tasks do load 'tasks/ambitious_seeder.rake' end end class NoSeedUpError < Exception end class NoSeedDownError < Exception end module Seeder def self.up(seeds) self.initialize_schema_seeds_table if seeds.kind_of?(Array) seeds.each { |seed| self.up(seed) } return end seed = seeds return if seed_already_up?(seed) begin seed.send(:up) rescue AmbitiousSeeder::NoSeedUpError abort "No upwards method for #{seed}!" end record_seed(seed) end def self.down(seed) self.initialize_schema_seeds_table return unless seed_already_up?(seed) begin seed.send(:down) rescue AmbitiousSeeder::NoSeedDownError abort "No downwards method for #{seed}!" end expunge_seed(seed) end private def self.db @db ||= setup_db end def self.setup_db ActiveRecord::Base.configurations = Rails.application.config.database_configuration ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations[Rails.env]) ActiveRecord::Base.connection end def self.seeds_table_name 'schema_seeds' end def self.seeds_table Arel::Table.new(seeds_table_name) end def self.initialize_schema_seeds_table seeds_table = seeds_table_name unless db.table_exists?(seeds_table) db.create_table(seeds_table, :id => false) do |table| table.column :seed, :string, :null => false end end end def self.seed_already_up?(seed) self.completed_seeds.include? seed.seed_name end def self.record_seed(seed) seeds_table.insert seeds_table["seed"] => seed.seed_name end def self.expunge_seed(seed) seeds_table.where(seeds_table["seed"].eq(seed.seed_name)).delete end def self.completed_seeds db.select_values(seeds_table.project(seeds_table['seed']).to_sql) end end class Seed def self.seed_name self.to_s.gsub(/seed$/i, '').underscore end def self.up raise AmbitiousSeeder::NoSeedUpError end def self.down raise AmbitiousSeeder::NoSeedDownError end end end