Al's blog

Alexis Toulotte

17 juil 07

Nouvelle venue

Guinness

Elle s’appelle Guinness ;)

10 juil 07

Fixtures on Rails

Il est assez fréquent d’avoir du contenu à pré-remplir dans une base de données lors du déploiement d’une application.

La plupart du temps on se fait un script SQL qui fait les insertions. En Rails, c’est mieux, on mets les insertions dans les scripts de migration et ça roule.

Petit hic, mettons que l’on a beaucoup de données et contenant des champs text, le script de migration va vite devenir illisible. Pour ça il y a les Fixtures. Seulement, ce n’est pas géré par les migrations (de base). Les fixtures sont représentés grâce à des fichiers YAML décrivant vos modèles.

Voilà un petit script à rajouter dans le répertoire /lib/ (nommez-le create_fixtures.rb) :

require 'active_record/fixtures'
 
module CreateFixtures
 
  FIXTURES_LOCATION = 'db/fixtures'
 
  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
 
  def migrate_with_fixtures(direction)
    migrate_without_fixtures(direction)
    return if :down == direction
    version = ActiveRecord::Migrator.current_version + 1
    cnx = ActiveRecord::Base.connection
    files = Dir["#{FIXTURES_LOCATION}/[0-9]*_*.yml"].each do |file|
      next unless file.gsub(/.*/([0-9]+)_.*.yml/, '1').to_i == version
      table_name = file.gsub(/.*/[0-9]+_(.*).yml/, '1')
      Fixtures.new(cnx, table_name, nil, file.gsub(/(.*).yml/, '1')).insert_fixtures
    end
  end
 
end
 
ActiveRecord::Migration.extend(CreateFixtures)

Ensuite, rajouter cette ligne dans le fichier config/environment.rb :

require File.dirname(__FILE__) + '/../lib/create_fixtures'

Voilà la chose est en place. Maintenant voyons l’utilisation.

Vous avez juste à créer un répertoire db/fixtures dans votre application et y mettre vos fichiersYAML. Nommez vos fichiers de la sorte :

<numéro_de_migration><nom_de_la_table>.yml

Rien de mieux qu’un petit exemple :

$ cat db/fixtures/002_users.yml
login: admin
hashed_password: d033e22ae348aeb5660fc2140aec35850c4da997
status: administrator

Ici, l’utilisateur administrateur sera directement ajouté à la fin de la deuxième migration. Vous pouvez bien-entendu mettre plusieurs fichiers de fixtures pour une même migration et créer des utilisateurs par exemple après la deuxième ou même la 42e migration.