list.blogug.ch updates

Posted by Patrice Neff Thu, 07 Sep 2006

This morning in the train I finally came around to fix a few issues with list.blogug.ch that had prevented a release for a while. The big change: search is now fast!

the search uses a Ferret index with the acts_as_ferret module. Ferret is basically the Ruby version of Lucene.

And the URLs are normalized when a new entry is added. This should leave us with far fewer duplicates than we now have. I find most of the duplicates when checking the new submissions but it still was an annoyance.

Ruby on Rails en español

Posted by Patrice Neff Tue, 28 Feb 2006

Eso es especialmente para mis amigos de Perú que hablan español: ya ustedes pueden aprender Ruby on Rails. En su weblog Juan tiene más informaciones sobre Ruby on Rails.

Juan Lupión translated two introductions to Spanish. En marcha con Ruby on Rails (original Rolling with Ruby on Rails) and En marcha con Ruby on Rails, y II (the second part). And only know have I discovered his Web site Sobre Rails, a Spanish Ruby on Rails site.

(Via O'Reilly Ruby)

Canada on Rails

Posted by Patrice Neff Wed, 18 Jan 2006

The conference has been announced. This is to my knowledge the first conference fully dedicated to . Cost ist 250 Canadian Dollars.

The conference ist from April 13 to April 14. I'm planning to go back from Peru mid-April and a layover in Canada sounds very attractive. But I probably couldn't fly directly (and I don't want to change planes in the US of A) and it might be quite expensive anyway. So I guess I won't be able to take the opportunity. But sure would be fun (and a learning experience which is one of my definitions for fun).

Schöne URLs mit Rails

Posted by Patrice Neff Sat, 26 Feb 2005

Version 0.10 brachte als grosse Neuerung die Routes mit. Heute hatte ich Gelegenheit, diese in meiner aktuellen Anwendung zu testen. Ich bin sehr angetan davon. Nun kann an einer zentralen Stelle sowohl das Rewriting für eingehende wie auch für die generierten URLs konfiguriert werden.

Details wurden bereits woanders aufgeschrieben, zum Beispiel in den Routes Beispielen von Scott oder im Handbuch zum Upgrade.

Ruby on Rails 0.10

Posted by Patrice Neff Fri, 25 Feb 2005

Gestern wurde wieder eine neue Rails Version veröffentlicht, nämlich Version 0.10.

Eine Funktion begeistert mich besonders, und zwar kann in Rails nun URL Rewriting mit Ruby Syntax definiert werden. Diese Funktion nennt sich Routing. Neu muss also nicht mehr im Apache mit mod_rewrite Regeln gezaubert werden um schöne URLs zu erhalten. Zudem, und das ist wohl der grösste Vorteil, werden die Routing Regeln auch verwendet um Links zu generieren. Wenn ich also mit den entsprechenden Rails Funktionen auf einen Eintrag verlinke, wird automatisch mit einer "schönen URL" verlinkt. Besonders witzig finde ich, dass ich genau das in einem aktuellen Projekt unbedingt brauche. Kommt also gerade rechtzeitig.

Neu ist das Paket Action Web Service, welches Webservices mit Rails zum Kinderspielt macht - und zwar sowohl das Schreiben eines Webservices wie auch das Zugreifen auf einen bestehenden. Habe damit noch nicht rumgespielt, kann also nichts dazu sagen. Tönt aber schon mal sehr interessant.

Fehler-Behandlung in Rails

Posted by Patrice Neff Thu, 27 Jan 2005

Ruby arbeitet sehr stark mit Exceptions, was die Fehlerbehandlung relativ einfach macht. Auch das Rails Framework arbeitet mit Exceptions. So wirft zum Beispiel der Code
Project.find(@params["id"])
den Fehler ActiveRecord::RecordNotFound. Doch nachdem ich bei Rails sowieso so wenig Code schreiben muss, finde ich es irgendwie nicht sehr elegant für die Fehlerbehandlung noch viel zu schreiben. So sah mein erster Anlauf aus:

begin
@project = Project.find(@params["id"])
@page_title = "Project: " + @project.title
rescue ActiveRecord::RecordNotFound
@page_title = "Project not found"
render "layouts/error", 404
end

Und das ganze für jede Methode in dem Controller. Ich bin dann über Blöcke in Ruby gestolpert. Siehe den Link für eine Erklärung, was das ist.

Damit habe ich im ApplicationController die Methode handle404 implementiert:

def handle404(pagetitle)
begin
yield
rescue ActiveRecord::RecordNotFound
@page_title = pagetitle
render "layouts/error", 404
end
end

So sieht der Code von vorher nun wie folgt aus:

handle404("Project not found") {
@project = Project.find(@params["id"])
@page_title = "Project: " + @project.title
}

Das bewirkt, dass im RecordNotFound-Fall ein 404 Fehler mit dem Titel "Project not found" generiert wird.

So finde ich das schon recht elegant gelöst. Da ich aber erst seit sehr kurzer Zeit mit Ruby arbeite, weiss ich aber noch nicht, ob das so wirklich okay ist.

Rails in den Medien

Posted by Patrice Neff Sat, 22 Jan 2005

Auf Ruby on Rails aufmerksam geworden bin ich durch einen Artikel in Linux Magazin oder ähnlich. Wenn ich da schon gewusst hätte, dass Rails momentan so gehyped wird, ich hätte wahrscheinlich nicht damit begonnen. Das hat damit zu tun, dass ich eine extreme Abgenigung gegen jede Art von Hypes habe, ganz speziell wenn es um Programmiersprachen etc. geht. Aber ich bin froh, habe ich mich dieses mal nicht von diesen Gedanken leiten lassen.

Nun, wieso Hype? Rails wurde gestern mit einem Slashdot Artikel ausgezeichnet. Dieser verweist auf einen sehr guten Artikel bei ONLamp namens Rolling with Ruby on Rails. Dieser erklärt kurz, was Ruby und Rails sind, zeigt die Installation unter Windows und führt dann mit einem Tutorial in Rails ein.

We developers often hear the excessive hype that always seems to accompany something new. I can just imagine that skeptical look on your face as you hear my dubious claims. Ten times faster development, indeed!

I'm not asking you to accept this on blind faith. I'll show you how to prove it to yourself. First, I'll install the needed software. Then I will lead you through the development of a web application.

Unbedingt lesen!

Cross-Site Scripting bei Rails

Posted by Patrice Neff Thu, 20 Jan 2005

Gerade habe ich noch über SQL Injection bei Rails geschrieben und nun habe ich mich auch schon dem Thema Cross-Site Scripting zugewendet. Wieder beziehe ich mich auf das Dokument Securing your Rails, dieses mal auf das Kapitel 2.

Bei Rails ist die Verteidigung gegen Cross-Site Scripting so simpel, dass es keine Ausrede mehr gibt, das nicht zu tun. Bei PHP rege ich mich jeweils ein wenig über den sehr langen Funktionsnamen htmlspecialchars auf. Bei Rails lautet die Funktion einfach h. Und das ist auch richtig so, wird doch diese Funktion extrem oft benötigt.

In der Praxis sieht das dann so aus:
<%=h @customer.company %>

Kurz und prägnant also. Wird der Wert in einer Funktion, wie zum Beispiel link_to verwendet, nehme man folgenden Code:
h(@project.title)

SQL Injection bei Rails

Posted by Patrice Neff Thu, 20 Jan 2005

Sicherheit von Web-Applikationen ist eines meiner Lieblingsthemen. So habe ich vor einigen Jahren ein Papier zum Thema SQL Injection und Cross-Site Scripting geschrieben. Dieses diente damals einem Firmen-internen Vortrag bei meiner Lehrfirma. Der Schwerpunkt dieses Papiers lag auf der Verhinderung der Angriffe mit Active Server Pages.

Das Thema ist nach wie vor aktuell, und nach wie vor gibt es da viel zu tun. Bei der Evaluation von Ruby on Rails ist es für mich auch wichtig, wie ich da SQL Injection und Cross-Site Scripting verhindern kann. Das Manual Securing your Rails ist prominent auf der Startseite des Bereiches Dokumentation verlinkt und gibt Auskunft.

Erstmal kümmert sich Rails um sehr viele Dinge selber. So werden ja viele Funktionen für den Datenbank-Zugriff der Daten automatisch generiert und diese sind gegen SQL Injection Probleme geschützt. Um bei einer eigenen Query (find_all heisst die Funktion dazu) keine Probleme damit zu erhalten, müssen die Benutzer-Eingaben bereinigt werden. Dazu kann man eine Methode verwenden, welche der Möglichkeit von "Prepared Statements" in anderen Frameworks nicht unähnlich ist. Ein Beispiel:

Customer.find_all [ "company = ?", company ]

Dies gibt mir alle Kunden zurück, deren Firmenname mit dem Wert der Variable company übereinstimmt. (Diese Funktion muss seit Rails 0.9.3 dank den "dynamic finders" nicht mehr mit find_all implementiert werden.)

Eine Schwierigkeit, die ich hatte, war eine LIKE Abfrage. Ich hatte eine Suchabfrage mit einer WHERE company LIKE '%eingabe%' Bedingung. Erster Versuch war dann so etwas:

Customer.find_all [ " company LIKE '%?%' ", company ]

Doch das führt nicht zum gewünschten Resultat. Denn da herauskommt, wenn company z.B. den Wert "test" enthält: company LIKE '%'test'%'. Um die Variable company werden als Hochkommas eingefügt, so dass ich mit dieser Variante zwei Hochkommas zu viel in der Abfrage haben werde. Dann habe ich im #rubyonrails IRC Channel nachgefragt und präsentiert wurde mir die Antwort, auf die ich eigentlich selber hätte kommen sollen. Und so macht man's richtig:

Customer.find_all [ " company LIKE ? ", '%#{company}%' ]

Der Ausdruck #{company} ist eine Möglichkeit, in einem String den Wert der Variable zu verwenden. Die beiden Prozentzeichen werden also aus der Anfrage rausgenommen und direkt in den Abfrage-Wert reingepackt. So kommen die Hochkommas um den ganzen Ausdruck mit den Prozenten und alles ist in Ordnung.

Also nochmals die Kurzfassung. Für normale Abfragen verwende man
Customer.find_all [ "company = ?", company ]
und wenn man eine LIKE '%xx%' Abfrage erstellen möchte, kommt
Customer.find_all [ " company LIKE ? ", '%#{company}%' ]
zum Zuge.

Rails Layout Wrapping

Posted by Patrice Neff Wed, 19 Jan 2005

Ruby on Rails hatte ich bereits erwähnt. Mittlerweile habe ich weiter damit programmiert und bin sehr begeistert davon. Entsprechend gibt es in diesem Blog jetzt auch eine eigene Kategorie dafür.

Heute hat mich unter anderem die Layout-Funktion von Rails begeistert. Meistens werden Layouts mit einem Include für den oberen Teil der Seite und einem für den unteren Teil realisiert. Das sieht dann normalerweise so aus (Pseude-Code):

inkludiere "oben.html"
Inhalt der aktuellen Seiten.
inkludiere "unten.html"

So kann man oben.html und unten.html ändern, wenn am Layout des gesamten Aufrittes etwas geändert werden soll. Un Rails kann man das genau umkehren. Ich sage also im Layout, wo der Inhalt reinkommt und "that's it."

Details gibt es auf einer eigenen Howto-Seite im Wiki: Howto Wrap Views With Layouts.