Mit ‘Rails’ getaggte Artikel

RoR-Migrations und PostgreSQL-Datentypen

Montag, 01. März 2010

Migrationsskripte sind in Ruby on Rails das Konzept, um die Entwicklung von Datenbanken im Verlaufe der Produktentwicklung zu verwalten und zu steuern. Da es sich bei ihnen um Ruby-Skripte handelt, steht einem auch der volle Funktionsumfang von Ruby on Rails zur Verfügung.
Ein Hauptprinzip der Migrationsskripte ist deren Datenbankneutralität. Sie soll es ermöglichen, mit möglichst geringem Aufwand die Datenbank wechseln zu können. Dies geht auf Kosten der Unterstützung spezieller Datenbank-Features.
Arbeitet man nun mit einer PostgreSQL-Datenbank und möchte man seine Spalten auch mit PostgreSQL-spezifischen Datentypen versehen, so kann man das wie folgt bewerkstelligen:

In der Methode “native_database_types” der Klasse “ActiveRecord::ConnectionAdapters::PostgreSQLAdapter” werden die Mappings für die SQL-Datentypen definiert, die von den Migrationsskripten im Zusammenhang mit einer PostgreSQL-Datenbank benutzt werden. Genau diese Methode kann man nun überschreiben, um die Mappings anzupassen.

class ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
def native_database_types
{
:primary_key => "bigserial primary key",
:string      => { :name => "character varying", :limit => 255 },
:text        => { :name => "text" },
:integer     => { :name => "integer" },
:float       => { :name => "float" },
:datetime    => { :name => "timestamp" },
:timestamp   => { :name => "timestamp" },
:time        => { :name => "time" },
:date        => { :name => "date" },
:binary      => { :name => "bytea" },
:boolean     => { :name => "boolean" },
:bigint      => { :name => "int8" }
}
end
end

Nun kann man diese Definition beispielsweise in psql_ext.rb im lib-Verzeichnis speichern und sie per require ‘psql_ext’ in die Migrationsskripte einbinden.


Christian Borkowski


Ruby On Rails – Vorsicht bei der Spaltenbenennung!

Montag, 19. Mai 2008

Getreu den Grundprinzipien von Ruby On Rails „Don’t repeat yourself“ und „Convention over configuration“, versucht das Webframework dem Entwickler die Datenbankanbindung zu erleichtern. Hält man sich an die Konventionen, so genügt es zum Beispiel, die Spalten einer Tabelle nur in der Datenbank festzulegen. Zur Laufzeit stehen einem automatisch Zugriffsmethoden für die Spalten zur Verfügung. Diese werden einfach nach den Spaltennamen benannt. Es werden hierfür also keine Konfigurations- bzw. Mappingdateien mehr benötigt.

Problem

Allerdings führt dieser Mechanismus zu Einschränkungen bei der Auswahl der Spaltennamen. Tabellenspalten sollten nicht den selben Namen tragen wie Methoden der Klasse AciveRecord::Base oder der Klasse Object. Werden diese Einschränkungen nicht beachtet, resultiert dies unter Umständen in schwierig aufzufindenden Fehlern. Nennt man beispielsweise die Spalte einer Tabelle “class”, so wäre der konventionelle Zugriffsweg auf diesen Spaltenwert über eine Instanz t des Models dieser Tabelle: t.class

Da class aber eine Methode der Klasse Object (Basisklasse von ActiveRecord::Base) ist, erhält man mit t.class nicht den erwarteten Spaltenwert, sondern die Klasse der Instanzvariablen t. Benennt man eine Tabellenspalte nach einer Methode von ActiveRecord::Base, so wird also die Spaltenzugriffsmethode nicht zur Verfügung gestellt, da es ja bereits eine gleichnamige Methode gibt. Verwendet man nun diese entsprechend seiner Tabellenspalte benannte Methode, führt dies zu einem unerwartetem Programmverhalten.

Lösung

Es ist empfehlenswert, die erwähnten Einschränkungen bei der Spaltenbenennung zu beachten und damit die Probleme zu vermeiden. Möchte man dennoch eine seiner Spalten genau wie eine Methode von ActiveRecord::Base benennen, so kann man sich einfach einen eigenen getter schreiben:

    def get_class
 
    self.attributes["class"]
 
    end

Die Bezeichner, die man bei der Spaltenbenennung vermeiden sollte, können der Ruby- bzw. der Rails-API entnommen werden. (Members der Klassen Object und ActiveRecord::Base)


Christian Borkowski