Rails : YAML et ActiveRecord (et SQL plus généralement)
Par Christophe, jeudi 21 juin 2007 à 03:40 :: Développement :: #150 :: rss
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é...

Commentaires
1. Le jeudi 21 juin 2007 à 10:26, par shingara
2. Le jeudi 21 juin 2007 à 13:32, par Christophe
3. Le mardi 10 juillet 2007 à 04:33, par Christophe
Ajouter un commentaire
Les commentaires pour ce billet sont fermés.