Suite à mon précédent billet concernant la création d'un jeu de données propre à une migration en utilisant les fixtures ainsi qu'aux nouveautés concernant les migrations dans rails 2.1, quelques ajustements ont du être effectués.

Les fichiers de migrations sont désormais préfixées par un timestamp (exemple : db/migrate/20080618211857_create_admin_user.rb) et non plus par un simple identifiant incrémental. Vos fichiers de fixtures doivent désormais être préfixés par ce même timestamp (exemple : db/fixtures/20080618211857_users.yml).

Voici donc le script lib/create_fixtures.rb mis à jour :

require 'active_record/fixtures'

module CreateFixtures

FIXTURES_LOCATION = File.dirname(__FILE__) + '/../db/fixtures'
MIGRATIONS_LOCATION = File.dirname(__FILE__) + '/../db/migrate'

def self.extended(object)
class << object
alias_method :migrate_without_fixtures, :migrate unless method_defined?(:migrate_without_fixtures)
alias_method :migrate, :migrate_with_fixtures
end
end

private

def current_migration
version = ActiveRecord::Migrator.current_version
index = migration_files.find_index do |f|
version = '%03d' % version if version.to_s.size < 3
f =~ /\/#{version}_/
end
file = index ? migration_files[index + 1] : migration_files.first
file.gsub(/.*\/(\d+)_.*/, '\1')
end

def fixture_files
@fixture_files ||= Dir["#{FIXTURES_LOCATION}/[0-9]*_*.yml"].sort
end

def migration_files
@migration_files ||= Dir["#{MIGRATIONS_LOCATION}/[0-9]*_*.rb"].sort
end

public

def migrate_with_fixtures(direction)
migrate_without_fixtures(direction)
return if :down == direction
migration = current_migration
cnx = ActiveRecord::Base.connection
file = fixture_files.find do |f|
f =~ /\/#{migration}_/
end
return unless file
table_name = file.gsub(/.*\/\d+_(.*)\.yml/, '\1')
Fixtures.new(cnx, table_name, nil, file.gsub(/(.*)\.yml/, '\1')).insert_fixtures
end

end

ActiveRecord::Migration.extend(CreateFixtures)

Note : Cette version est compatible avec les anciennes version de rails.