Blog

MySQL5 Installation auf dem Leopard

Es wird weithin gemunkelt das Rails erst auf einem Mac so richtig Spass macht. Da Aptana leider noch vollkommen buggy ist, habe ich beschlossen das daß sowieso fällige neue Notebook ein Mac wird. Es hat sich gelohnt...wirklich wahr! Alles funktioniert sofort ein einwandfrei. Alles? Nicht alles...

Die MySQL Installation hat mir einen bunten Nachmittag beschert. Das Problem war das ich keinen Zugriff auf den root User bekam. Die Installation unter Macport schien einwandfrei zu laufen, aber allen Anleitungen und Tutorials zum Trotz konnte ich mich nicht mit der Datenbank verbinden. Hier also eine Zusammenfassung der Schritte die bei meinem Leoparden zum Erfolg führten:

1.) Xcode Tools installieren - soll auf der CD sein, die hatte ich aber schon weggepackt. Deswegen habe ca 1.1 GB http://developer.apple.com/tools/download/ gedownloadet

2.) Macports installieren - Die passende Anleitung dazu gibts hier: http://www.macports.org/install.php. Unbedingt auch die Shell Variablen anpassen und

sudo port selfupdate


ausführen. Erst dann sind die Ports richtig installiert.

3.) Jetzt kommt der erste Kunstgriff: Leopard weist den hostname per default als "localhost" aus und das bringt aus Sicht von MySQL alles durcheinander. Es muss zunächst ein neuer Hostname zugewiesen werden - was ungefährlich ist soweit ich das einschätzen kann:

hostname anderhost

4.) Nun die eigentliche Installation des Ports:

# Port installieren
sudo port install mysql5 +server

# Startsrcipte einrichten
sudo launchctl load -w /Library/LaunchDaemons/org.macports.mysql5.plist

# MySQL System Tabellen einrichten
sudo mysql_install_db5 --user=mysql 

5.) Soweit so gut. Jetzt sollte eigentlich Zugriff möglich sein, ist es aber nicht..zumindest bei mir. Folgendes Vorgehen schaffte Abhilfe:

# Den MySQL Server wieder anhalten
/opt/local/etc/LaunchDaemons/org.macports.mysql5/mysql5.wrapper stop

  

Plugins in Rails

Wer erstmal ein wenig mit Rails gearbeitet hat gewöhnt sich schnell daran, erst nach einem Plugin zu suchen, bevor man das Rad neu erfindet. Sicherlich hängt das auch mit zusammen, dass die Arbeit mit Plugins in Rails so wunderbar einfach ist. Möchte man z.B. eine Mailadresse validieren bevor man sie in die Datenbank schreibt, greift man überlicherweise zu einem mehr oder weniger komplexen Regulären Ausdruck.

In Rails sucht man aus der Fülle der vorhandenen Plugin eines heraus, ich nutze auf Empfehlung das Plugin Email Veracity Plugin zu erhalten unter http://rails.savvica.com/2007/11/6/email-veracity-plugin
Plugin Installation unter Rails (Windows)

ruby script/plugin install http://svn.savvica.com/public/plugins/validates_email_veracity_of


dann rattert es ein wenig auf der Kommandozeile und das Plugin ist installiert. Alles was noch bleibt ist den Model Klassen freundlich mitzuteilen welcher auf gültige E-Mailadressen geprüft werden sollen. Das geht so:

class Contact < ActiveRecord::Base  
  validates_email_veracity_of :email, :domain_check => false
end


In dem meisten Fällen verzichte ich auf den Domaincheck, bei dem der MX Record der Adresse geprüft wird. Zuschalten kann man dass immer noch wenn die Anzahl der gefakten Adressen im System ansteigt. Zumindest nach den letzten Kenntnissen die ich habe, ist die Gefahr von false-positives nicht ganz auszuschliessen.

assert_difference - Developers little helper

Testgetriebene Entwicklung (TDD) ist ein muß mit Rails. Wer sich dem versperrt steht sich selbst im Weg und wer nicht zuerst einen Test schreibt, sondern nach der Implementierung der Logik seinen Code irgendwie absichert, hat die umfassende Philosphie der Testgetriebenen Entwicklung noch nicht verstanden. In dem Fall hilft nur: http://www.amazon.de/xUnit-Test-Patterns-Refactoring-Signature/dp/013149...

Der Scaffolder erzeugt mit jedem Controller auch gleich die Unit Tests die diesen absichern. Dort wird eifrig gebraucht gemacht von assert_difference und nicht sofort erschliesst sich dem Neuling die komplette Syntax.

Aus dem Functional Test:

  def test_should_create_client
    # Nimm an das die sich Anzahl von Client.count sich nach dem Ausführen um 1 erhöht hat
    assert_difference('Client.count') do
      post :create, :client => { }
    end

    assert_redirected_to client_path(assigns(:client))
  end

Um das komplett verstehen zu können muss man sich die Implementierung der Funktion ansehen:

  def assert_difference(expressions, difference = 1, message = nil, &block)

Jetzt wird es klarer: expressions wird mittels eval ausgewertet, Angenommener Standardunterschied ist 1. Würde man also zwei neue Client Objekte erzeugen müsste der Testcode so aussehen:

    assert_difference('Client.count', 2) do
      post :create, :client => { }
      post :create, :client => { }
    end

Und tatsächlich läuft mein derart modifierter Test ohne Fehler.

Fazit: assert_difference ist ein sehr nützlicher Helfer der deb Testcode verkürzt hilft das DRY Prinzip einzuhalten.

Attachment_fu Windows Problem

Auf Windows Systemen kann attachment_fu unter Umständen die Datei nicht richtig berrechnen, weil das schreiben der Datei zulange dauert.

http://beast.caboo.se/forums/2/topics/1124


There were problems with the following fields:

* Size is not included in the list

Einfachste Lösung ist es die minimale Dateigröße runter zu schrauben:
has_attachment :content_type => ['application/pdf', 'application/msword', 'text/plain'],
:storage => :file_system,
:min_size => 1.kilobytes,
:max_size => 50000.kilobytes

Case Studie

Nebenher mal ein paar Beispiele zur Verwendung der eleganten "case" Syntax. Sicher eher ein Ruby Thema, aber wer sich mit Rails auseinander setzt kommt an Ruby nicht vorbei.

# chic und kurz. 
unit = "days"
case unit
  when "days"   then  "Day"
  when "weeks"  then  "Week"  
  when "months" then  "Month"
  when "years"  then  "Year"         
end  
#-> "days"

# PayPal und WorldPay verodert
# Mehrzeilige Anweisungen
# Am Ende noch ein Default Blcok
case provider
  when "PayPal", "WorldPay"
    compute_this
    prepare_that
  when "MetaCharge"
    compute_this
    prepare_that_completly_different
else
  compute_nothing
end

Achtung - Die Shebang Falle

Man kann schon einen bunten Nachmittag damit verbringen herauszufinden warum die schöne neue Rails Applikation nicht auf dem Linux Server laufen will der eigens dafür eingerichtet wurde. Alles was Rails zu sagen hat ist die Standardmeldung im Falle eines 500er Serverfehlers:

Application error
Rails application failed to start properly"

Das Apache Log meldet Sachen wie:


FastCGI: server "/www/blah/current/public/dispatch.fcgi" (pid 32163) terminated by calling exit with status '255'
FastCGI: can't start server "/www/blah/current/public/dispatch.fcgi" (pid 32163), execle() failed: No such file or directory
FastCGI: comm with server "/www/blah/current/public/dispatch.fcgi" aborted: idle timeout (60 sec)
FastCGI: incomplete headers (0 bytes) received from server "/www/blah/current/public/dispatch.fcgi"

Die Ursache für dafür hat sich die perfekte Tarnung zugelegt. Ein Auszug aus /public/dispatch.fcgi

#!c:/ruby/bin/ruby
#
# You may specify the path to the FastCGI crash log (a log of unhandled
# exceptions which forced the FastCGI instance to exit, great for debugging)
# and the number of requests to process before running garbage collection.
#

Und? Genau! Es ist der Shebang #!c:/ruby/bin/ruby
Obwohl auf Windows Systemen weitgehend wertlos, packt Rails den Pfad zum Ruby Interpreter dazu, was politisch sicher vollkommen korrekt ist. Also der Shebang einmal angepasst: #!/usr/local/bin/ruby und schon rollt Rails wieder.

Syndicate content