2010-02-26 11 views
11

Ich versuche, einige Nachschlagetabellen-Daten in einer YAML-Datei zu speichern, damit ich später, wenn ich meine App auf einem anderen Rechner einrichten muss, die Daten als Seed-Daten einlesen kann.Wie kann ich einige ActiveRecord-Modelle aus einer YAML-Datei laden und in der DB speichern?

Die Daten sind Zeug wie Auswahloptionen, und es ist ziemlich festgelegt, also keine Sorgen über die Live-Daten zwischen Serialisierung und Deserialisierung wechseln.

Ich habe die Daten auszugeben wie diese ...

file = File.open("#{RAILS_ROOT}/lib/tasks/questions/questions.yml", 'w') 
questions = Question.find(:all, :order => 'order_position') 
file << YAML::dump(questions) 
file.close() 

Und ich kann die Datei wie folgt laden ...

questions = YAML.load_file('lib/tasks/questions/questions.yml') 

aber wenn ich versuche, eine Frage zu speichern ich diese Fehler ...

>> questions[0].save 
NoMethodError: undefined method `save' for #<YAML::Object:0x2226b84> 

Was ist der richtige Weg, dies zu tun?

+0

Welche Version von Rails verwenden Sie? –

+0

Ich benutze Rails 2.3.5 – Ethan

Antwort

8

Ich habe versucht, Ihr Szenario zu laden, und ich hatte keine Probleme. Ich habe die folgenden Änderungen an Ihrer YAML Dateierstellung Logik:

yml_file = Rails.root.join('lib', 'tasks', 'questions', 'questions.yml') 
File.open(yml_file, 'w') do |file| 
    questions = Question.order(:order_position).to_a 
    YAML::dump(questions, file) 
end 

konnte ich die questions Liste abzurufen, wie folgt:

yml_file = Rails.root.join('lib', 'tasks', 'questions', 'questions.yml') 
question_attributes_list = YAML.load_file(yml_file).map(&:attributes) 
questions = Question.create(question_attributes_list) 
1

Wenn Sie Rails 2.3.4 (oder höher) verwenden, haben sie eine seeds.rb Datei, die in Ihren Anwendungen db Ordner gefunden werden kann. Auf diese Weise können Sie festlegen, grundlegenden aktiven Datensatz erzeugt, und wenn Sie Ihr neues Projekt eingerichtet haben, können Sie einfach anrufen:

rake db:seed 

Es gibt eine ausgezeichnete Railscast drauf here und ein gutes Blog-Post über sie here. Wenn Sie nicht Rails 2.3.4 verwenden (oder idealerweise 2.3.5), empfehle ich dringend, für diese coolen Funktionen und zusätzliche Sicherheit/Bugfixes zu aktualisieren.

+0

Danke, ja das ist ein großartiges Feature. Ich möchte die Daten in einer YAML-Datei speichern und mit 'same.rb' laden. Es gibt genügend Daten, die die Modellinstanziierungen direkt in 'samen.rb' schwer codieren würden. – Ethan

+0

Seeds.rb ist nur eine Ruby-Datei. Sie können YAML innerhalb von samen.rb laden, wie hier beschrieben (http://ruby-doc.org/core/classes/YAML.html), und einfach die Arrays durchlaufen, während Sie Model.create() ausführen. –

20

Erstellen Sie eine seed.yml Datei in db Verzeichnis. Fügen Sie für jedes Modell, das Sie erstellen möchten, ein YAML-Dokument hinzu. Dieses Dokument sollte eine Liste von Hash enthalten. Jeder Hash sollte Modellattribute enthalten.

users: 
     - login: jake 
      password: jake123 
      password_confirmation: jake123 
      first_name: Jake 
      last_name: Driver 

     - login: Jane 
      password: jane123 
      password_confirmation: jane123 
      first_name: Jane 
      last_name: McCain 

    categories: 

    products: 

In Ihrem seed.rb Datei

seed_file = File.join(Rails.root, 'db', 'seed.yml') 
config = YAML::load_file(seed_file) 
User.create(config["users"]) 
Category.create(config["categories"]) 
Product.create(config["products"]) 

Führen Sie die Rake Aufgabe, die Reihen

rake db:seed 
+0

Mann, das ist so nützlich zu wissen. Vielen Dank. Ist es in Rails 4 noch relevant? – Batman

+0

@ Batman Ich denke schon. Dies beruht auf dem Standard-YAML-Parser und der AR-Array-Erstellungsmethode. –

10

Ist die akzeptierte Antwort tatsächlich die Frage beantworten? Es sieht so aus, als ob der Fragesteller die Modelle speichern und nicht nur aus einer YAML-Datei abrufen möchte.

Um tatsächlich speichern das geladene Modell (s) zurück in die Datenbank müssen Sie ins Denken täuschen das Modell muss gespeichert werden. Sie können es mit diesem ziemlich schmutzigen Bit des Codes tun

questions = YAML.load_file("#{RAILS_ROOT}/lib/tasks/questions/questions.yml") 
questions.each{|q| q.instance_variable_set("@new_record", true); q.save} 

Es funktioniert und speicherte meine Speck ein oder zweimal.

+0

Danke, das war das bisschen, das ich brauche, um es zum Laufen zu bringen. – Jurgen

+0

Dies sollte die akzeptierte Antwort sein. Vielen Dank! – cschille

Verwandte Themen