2010-06-21 2 views
4

Il existe une table questions et un fichier de données questions.yml. Supposons qu'il n'y a pas de modèle 'Question'. 'Questions.yml' a quelques vidages de recodes de la tableComment charger les données d'un fichier .yml à la base de données?

--- 
questions_001: 
    title: ttt1 
    content: ccc1 
questions_002: 
    title: ttt2 
    content: ccc2 

Je veux charger les données du fichier yml, les insérer dans la base de données. Mais je ne peux pas utiliser rake db:fixtures:load, car il va traiter le contenu en tant que modèle 'erb', ce qui ne veut pas je veux

Donc je veux écrire une autre tâche de rake, pour charger les données manuellement.

Je peux lire les enregistrements par:

File.open("#{RAILS_ROOT}/db/fixtures/#{table_name}.yml", 'r') do |file| 
    YAML::load(file).each do |record| 
     # how to insert the record?? 
    end 
end 

Mais je ne sais pas comment les insérer.


Edit:

J'ai essayé:

Class.new(ActiveRecord::Base).create(record) 

et

class Dummy < ActiveRecord::Base {} 
Dummy.create(rcord) 

Mais rien inséré dans la base de données

Répondre

7

Essayez ceci après le chargement de la date du YML déposer au records:

class Question < ActiveRecord::Base 
    # Question model just to import the yml file 
end 
records.each { |record| Question.create(record) } 

Vous pouvez simplement créer un modèle juste pour l'importation. Vous n'avez pas besoin de créer le app/models/question.rb. Il suffit d'écrire le code ci-dessus dans le script responsable de l'importation.

MISE À JOUR:

Vous pouvez utiliser la fonction suivante:

def create_class(class_name, superclass, &block) 
    klass = Class.new superclass, &block 
    Object.const_set class_name, klass 
end 

source

File.open("#{RAILS_ROOT}/db/fixtures/#{table_name}.yml", 'r') do |file| 
    YAML::load(file).each do |record| 
    model_name = table_name.singularize.camelize 
    create_class(model_name, ActiveRecod::Base) do 
     set_table_name table_name.to_sym 
    end 
    Kernel.const_get(model_name).create(record) 
    end 
end 

Pour utiliser la connexion que vous pouvez directement utiliser les éléments suivants:

ActiveRecord::Base.connection.execute("YOUR SQL CODE") 
+0

@Jens Fahnenbruck, merci, mais je suppose qu'il n'y a pas de modèle 'Question', juste la table et le fichier yml. – Freewind

+0

J'ai cette limitation, car il y a des tableaux n'ont pas de modèles correspondants, tels que 'questions_tags' – Freewind

+0

J'ai mis à jour mon anser – jigfox

0

Ça a marché grâce à la réponse de @jigfox. Nous avons dû modifier un peu pour la mise en œuvre maintenant avec Rails 4.

table_names = Dir.glob(Rails.root + 'app/models/**.rb').map { |s| Pathname.new(s).basename.to_s.gsub(/\.rb$/,'') }  

table_names.each do |table_name| 
    table_name = table_name.pluralize 
    path = "#{Rails.root}/db/fixtures/#{table_name}.yml" 
    if File.exists?(path) 
    File.open(path, 'r') do |file| 
     y = YAML::load(file) 
     if !y.nil? and y 
     y.each do |record| 
      model_name = table_name.singularize.camelize 
      rec = record[1] 
      rec.tap { |hs| hs.delete("id") } 
      Kernel.const_get(model_name).create(rec) 
     end 
     end 
    end 
    end 
end 
1
Ce

charge les appareils dans le courant RAILS_ENV, qui, par défaut, est le développement.

$ rake db:fixtures:load 
Questions connexes