Archive for the ‘Tricks’ Category

Daten aus der IRB-Console speichern mit einer Zeile

Dienstag, Mai 27th, 2008

Rails bringt ein Konsolenskript mit, welches IRB mit der Rails-Umgebung lädt. Dort stehen dann alle im Rails-Projekt verwendeten Klassen zur Verfügung. Erreichen kann man diese Konsole unter der Eingabe von “ruby script/console [environment]” Wird keine Umgebung (environment) angegeben, ist die Development-Umgebung gewählt. Das bedeutet, die Datenbankverbindung wird zur Development-Datenbank aufgebaut. Alternativ kann man hier auch “production” (oder “test”, etc.) angeben.

Nun kann man beliebige Ruby-Befehle eingeben und das Ergebnis gleich begutachten. Aber darum soll es hier jetzt gar nicht im Detail gehen. Die Konsole ist ungeheuer praktisch, wenn man Daten aus der Datenbank auslesen möchte, die über komplexe Models verknüpft sind. Statt direkt auf der SQL-Konsole mit langen JOINs rumzubasteln, benutzt man einfach ein die Model-Klassen aus dem Rails-Projekt.

Dateien schreiben mit der File-Klasse

Aber wie bekommt man diese Daten aus der Konsole? Die File-Klasse ermöglicht es Dateien mit einem Block zu schreiben, so dass der ganze Befehl nur eine einzige Zeile benötigt:

File.open("output.txt", "w") { |f| f.puts "Ausgabe" }

Das erzeugt eine Datei output.txt im aktuellen Verzeichnis und schreibt den Inhalt “Ausgabe” hinein. (Das “w” als zweiter Parameter gibt den schreibmodus an, vorherige Inhalte der Datei werden gelöscht!)

Nehmen wir als einfaches Beispiel an, uns interessieren alle Benutzernamen eines fiktiven Projekts, nach Name sortiert. In der Konsole erhalten wir durch Eingabe von

User.find(:all, :order => :name)

eine solche Liste als Array von User-Objekten. Mit einem kurzen Block können wir die gewünschten Namen Ausgeben:

User.find(:all, :order => :name).each { |user| puts user.name }

Um diese Liste jetzt aus der Konsole zu bekommen, setzen wir diese Zeile innerhalb des File-Blocks ein. Wichtig hierbei ist, dass die puts-Anweisung auf das File-Objekt angewendet wird, damit die Ausgabe dorthin umgeleitet wird!

File.open("output.txt", "w") { |f| User.find(:all, :order => :name).each { |user| f.puts user.name }  }

Fertig! Jetzt kann die Konsole mit der Eingabe von quit oder exit beendet werden und im gleichen Verzeichnis findet sich eine Datei mit dem Namen output.txt, die die Liste enthält.

Die Abfrage im Beispiel ist natürlich trivial- bei komplexeren Abfragen mit viel Model-Logik ist es aber eine große Erleichterung.

Automatisch richtige Pfad-Trennzeichen benutzen (Linux/Windows)

Donnerstag, April 10th, 2008

Häufiges Szenario ist die Entwicklung unter Windows (mit InstantRails) und das Deployment unter Linux.
Greift man innerhalb der Rails-Anwendung auf das Dateisystem zu, hat man hierbei ein Problem mit den Pfadangaben. Unter Windows trennt ein Backslash die einzelnen Verzeichnisse, unter Linux* jedoch ein normaler Schrägstrich (Slash).

Man könnte eine Trennzeichen-Variable definieren und diese dann in jedem nur erdenklichen Verzeichnis-String einsetzen. Den Wert dieser Variablen könnte man abhängig von der aktuellen Umgebung (Development vs. Production) machen, um ihn nicht vor jedem Deploy ändern zu müssen. Das macht die Pfadangaben-Strings innerhalb der Anwendung nicht nur unübersichtlich und fehleranfällig sondern ist auch von der Denkweise falsch: Das Trennzeichen hängt ja nicht von der Rails-Umgebung sondern vom Betriebssystem ab- falls es mehrere Railsentwickler mit unterschiedlichen Betriebssystemen gibt, funktioniert das ganze schon wieder nicht.

Die Lösung bringt File.join(*parts)

File.join fügt einzelne Strings als Pfadangaben mit dem jeweils Betriebssystem-spezifischen Trennzeichen zusammen:

File.join('foo', 'bar')  # => "foo/bar" (Linux/Mac OS)

File.join('foo', 'bar')  # => "foo\bar" (Windows)

Es wird keine Operation auf dem Dateisystem ausgeführt; der Pfad muss also nicht existieren. Möchte man das Trennzeichen isolieren, genügt ein File.join(”",”") (falls es eine kürzere Schreibweise gibt, lasst es mich wissen).

*und natürlich bei allen anderen *NIX-”Geschmacksrichtungen”, wie BSD oder Darwin (Mac OS)

AltGr-Taste im IRB von InstantRails aktivieren

Samstag, März 22nd, 2008

InstantRails ist eine einfache Möglichkeit, unter Windows Rails-Anwendungen zu Entwickeln. Ruby, Rails, Apache und MySQL sind in diesem Paket gebundelt und müssen nicht installiert werden. Das Paket kann einfach entpackt werden und man kann loslegen (der Pfad darf allerdings keine Leerzeichen enthalten).

Die Freude wärt aber nur kurz, wenn man irb bzw. die Rails-Konsole über script/console benutzen möchte.

Dort funktionert nämlich die AltGr-Taste nicht, d.h. man kann kein @, [, ], oder | eingeben. Ich hatte dieses Problem bereits früher (konnte es beheben und vergaß es) und bekam es jetzt wieder beim Umstieg auf InstantRails 2 (mit Rails 2.0.2).

Lösung:

Man muss eine .inputrc-Datei erzeugen, die AltGr-Tastenkombinationen beschreibt. Diese Datei ist bei InstantRails schon enthalten. Sie enthält folgendes

"\M-[": "["
"\M-]": "]"
"\M-{": "{"
"\M-}": "}"
"\M-\\": "\\"
"\M-|": "|"
"\M-@": "@"
"\M-~": "~"
"\M-$": "$"

Und befindet sich im Verzeichnis <InstantRails>\ruby\bin\inputrc.euro

In der Datei irb.bat im gleichen Verzeichnis muss hinter dem @ECHO OFF folgende Zeile hinzugefügt werden:

SET INPUTRC=<pfad-zur-inputrc>\.inputrc

Es gibt noch andere Lösungsvorschläge, die aber zumindest für InstantRails nicht funktionieren. Die .inputrc gehört am besten ins Homedirectory des aktuellen Benutzers, also nach c:\Dokumente und Einstellungen\<Benutzername>. Wichtig sind in diesem Fall Anführungszeichen um die Pfadangabe, da sie Leerzeichen enthält!

Falls es eine Möglichkeit gibt die inputrc.euro aus dem bin-Verzeichnis direkt (ohne Angabe des Pfades) einzubinden, lasst es mich wissen. Ich habe bei kurzem überfliegen der Umgebungsvariablen aber nichts passendes gefunden, beispielsweise eine Variable mit dem aktuellen Pfad zum InstantRails-Verzeichnis.

(Ergänzung: Selbstverständlich muss man die .inputrc nicht woanders hin kopieren sondern kann Sie direkt mit absoluter Pfadangabe aus dem bin-Verzeichnis einbinden. Da man das InstantRails-Verzeichnis aber umbenennen und umkopieren kann, und InstantRails trotzdem funktioniert, ist eine absolute Pfadangabe zu “gefährlich”)