Websiteentwicklung: Ruby on Rails: Datenbank und Model
Wie arbeiten Datenbank und Model zusammen?
Datenbank verändern mit Migrations
BearbeitenDie Problemstellung
BearbeitenBei Web-Applikationen tritt folgendes Problem auf: im Laufe der Entwicklung ändert sich das Datenbank-Schema. Gleichzeitig ist die Applikation aber schon im Echt-Betrieb, man kann die Produktions-Datenbank nicht einfach löschen und von Grund auf neu bauen.
Es ist also notwendig, die Veränderungs-Schritte der Datenbank zu speichern, und auf allen Servern (verschiedene Entwicklungs-Rechner, Test, Produktion) in der gleichen Reihenfolge nachzuvollziehen.
Ruby on Rails bietet dafür eine Lösung: Migrations.
Eine Migration ist dabei ein Schritt der Veränderung - wobei dieser Schritt immer in beide Richtungen definiert ist.
Im Ordner /db/migrations/ sind die einzelnen Migrations gespeichert.
Nach der Erzeugung des scaffolds für hallo sieht das z.B. so aus:
20090829142637_create_hallos.rb
Diese Datei enthält das Anlegen der Tabelle für das Model Hallo:
class CreateHallos < ActiveRecord::Migration def self.up create_table :hallos do |t| t.string :von t.text :meldung t.string :farbe t.timestamps end end def self.down drop_table :hallos end end
Eine Migration erstellen
BearbeitenMit dem Kommandozeilen-Befehl
↯rake db:migration↯
rake db:migrate (siehe auch rake -T [korrigiert uwe.schimon@mailpost.de])
werden jeweils alle neuen Migrations ausgeführt. Mit
rake db:rollback
kann der letzte Schritt rückgängig gemacht werden. Welcher Migrations-Schritt bereits angewandt wurde wird in der Datenbank salbst gespeichert, in der Tabelle schema_migrations
Wenn man die Datenbank verändern will - zum Beispiel um eine neue Spalte in die Tabelle einzufügen - so kann man selbst eine migration erzeugen:
rails generate migration AddWiederholungToHallo wiederholung:integer
Aus der Namens-Konvention erzeugt der Generator gleich einen guten Entwurf für die Migration:
class AddWiederholungToHallo < ActiveRecord::Migration def self.up add_column :hallos, :wiederholung, :integer end
def self.down remove_column :hallos, :wiederholung end end
Was noch zu tun ist
BearbeitenDazu gibt es einen Rails Guide [1] Migrations |
Nach dem Hinzufügen oder Löschen von Spalten aus der Tabelle muss das Model nicht verändert werden!
Die Spalten werden automatisch als Attribute des Objekts übernommen. Der Controller muss meist auch nicht verändert werden.
Nur die Views (Eingabemasken, Anzeige des Objekts) müssen verändert werden!
Daten lesen und speichern mit dem Model
BearbeitenWir arbeitet das Model mit der Datenbank zusammen? Das werden wir nun interaktiv erforschen
Daten Suchen und Finden
BearbeitenEs gibt eine interaktive Shell für Rails. Gestartet wird sie mit
rails console
Nun kann man ruby-befehle eintippen und sieht sofort das Ergebnis.
>> Hallo.find(1) => #<Hallo id: 1, von: "Brigitte", meldung: "Hallo Welt, es freut mich sehr Dich zu sehen!", farbe: "#FF0000", created_at: "2009-08-29 14:28:54", updated_at: "2009-08-29 14:28:54">
Die Klasse Hallo hat (wie jedes Klasse des Models) eine Methode find. Mit find(1) suche ich nach dem Objekt das in der Datenbank die id=1 hat.
Mit find(:all) suche ich nach allen Objekten. Das gibt viel output (hier gekürzt!)
>> Hallo.find(:all) => [#<Hallo id: 1, von: "Brigitte">, #<Hallo id: 2, von: "Karin">, #<Hallo id: 3, von: "Hilmar">]
Daten anlegen
BearbeitenHier kann man auch neue Objekte anlegen:
>> h = Hallo.new => #<Hallo id: nil, von: nil, meldung: nil, farbe: nil, created_at: nil, updated_at: nil> >> h.von = "Tippse" => "Tippse" >> h.meldung = "Auch ohne das Web kann ich einfügen" => "Auch ohne das Web kann ich einf\201gen" >> h => #<Hallo id: nil, von: "Tippse", meldung: "Auch ohne das Web kann ich einf\201gen", farbe: nil, created_at: nil, updated_at: nil>
das Objekt existiert derzeit nur im Hauptspeicher, im laufenden Programm - es ist noch nicht in der Datenbank gespeichert. (Deswegen hat es auch noch keine id). mit save kann ich versuchen das Objekt zu speichern:
>> h.save => false
Der Rückgabewert false bedeutet: das Speichern hat nicht funktioniert. Warum? Weil die Farbe nicht gespeichert werden kann, ich habe ja eine Validierung auf dem Farb-Feld Programmiert:
# im Model validates_format_of :farbe, :with => /^#......$/, :message => "nur Farb-Code mit # und 6 Stellen (hexadezimal) erlaubt"
Also muss ich die Farbe korrekt setzen und kann dann speichern:
>> h.farbe="#00FF00" => "#00FF00" >> h.save => true
Danach hat h auch eine id, und werte in created_at und updated_at:
>> h => #<Hallo id: 7, von: "Tippse", meldung: "Auch ohne das Web kann ich einf\201gen", farbe: "#00FF00", created_at: "2009-08-31 11:46:06", updated_at: "2009-08-31 11:46:06">
Weitere Quellen
Bearbeiten- ↑ Rails Guide Migrations
- ↑ Rails API ActiveRecord Migration