S'est posé à moi le problème de transformer le contenu du fichier YAML lib/places.yml suivant en lignes SQL représentatives :

- USA:
  - California:
    - Los Angeles Area
    - San Diego Area
- Europe:
  - France:
    - Ile-de-France
    - Aquitaine:
      - Gironde:
        - Bordeaux
    - Alsace
  - Poland:
    - Mazowieckie:
      - Warszawa

..., fichier yaml qui devient :

+----+------------------+-----------+
| id | name             | parent_id |
+----+------------------+-----------+
|  1 | USA              |         0 | 
|  2 | California       |         1 | 
|  3 | Los Angeles Area |         2 | 
|  4 | San Diego Area   |         2 | 
|  5 | Europe           |         0 | 
|  6 | France           |         5 | 
|  7 | Ile-de-France    |         6 | 
|  8 | Aquitaine        |         6 | 
|  9 | Gironde          |         8 | 
| 10 | Bordeaux         |         9 | 
| 11 | Alsace           |         6 | 
| 12 | Poland           |         5 | 
| 13 | Mazowieckie      |        12 | 
| 14 | Warszawa         |        13 | 
+----+------------------+-----------+

..., contenu qui sera facilement utilisable, notamment avec acts_as_tree.

Voici la (très petite) classe que j'ai créé pour l'occasion (lib/yaml_to_ar.rb):

 require 'yaml'
 class YAML_to_AR


   def initialize(file)
     @data = File.open(file) { |yf| YAML::load( yf ) }
   end


   def insert(with_class, parent_id = 0, data = @data)
     if data.is_a?(Array)
       data.each do |value|
         insert(with_class, parent_id, value)
       end
     elsif data.is_a?(Hash)
       data.each do |key, value|
         new_line = with_class.create(:name => key, :parent_id => parent_id)
         insert(with_class, new_line.id, value)
       end
     elsif data.is_a?(String)
        with_class.create(:name => data, :parent_id => parent_id)
     end
   end


 end

Classe qui s'utilise simplement dans une migration, comme ceci par exemple (@ db/migrate/003_create_places.rb) :

 class CreatePlaces < ActiveRecord::Migration
   def self.up
     create_table :places do |t|
       t.column :name, :string
       t.column :parent_id, :integer
     end

     require 'lib/yaml_to_ar'
     loading = YAML_to_AR.new('lib/places.yml')
     loading.insert(Place)

   end

   def self.down
     drop_table :places
   end
 end

Ensuite, peut se poser la question de rajouter une méthode qui permette de modifier la table avec un fichier YAML du même style, se basant sur une sorte de "diff" entre les deux, mais vu que le problème ne s'est jamais présenté...