June 1, 2007

Legacy-Tabellen mit Ruby on Rails

Ich möchte hier auf eine Frage eingehen, die der Flo in einem Kommentar gestellt hat.

Es geht darum, wie man Legacy-Schemata in Rails verwenden kann, die beispielsweise nicht über eine ID-Autoinkrement-Spalte verfügen.

Nun ich habe dazu folgendes gemacht, nur um das Prinzip zu zeigen. Dies ist keine 1-zu-1-Anleitung für den unbedarften Nachahmer:

  1. Öffnen eines bestehenden Rails-Projekts
  2. In der zugehörigen Datenbank: Anlegen eines Dummy-Schemas ‘Mytable’
  3. Im Projekt-Verzeichnis-Baum: Anlegen einer ActiveRecord-Klasse ‘Mytable’ für meine Legacy-Tabelle
  4. Anpassungen für einen minimalen Showcase eingefügt.
  5. Rails-Konsole öffnen und
    1. Daten suchen (kein Inhalt in Mytable)
    2. Objekt anlegen mit new und anschließend speichern mit save
    3. Objekte suchen (jetzt ist eines da!)

Im Folgenden zeige ich die einzelnen Schritte:

  1. Öffnen eines bestehenden Rails-Projekts
    kein Kommentar
  2. Anlegen eines Dummy-Schemas ‘Mytable’
            pg-269:~/rp ghadir$ mysql -u root population_development
    
    
            mysql> create table MYTABLE (
                -> 
                ->   objectidentifier int not null,
                ->   name varchar(40), 
                ->   constraint  MYTABLEPK PRIMARY KEY  (objectidentifier)
                -> )
                -> 
                -> ;
            Query OK, 0 rows affected (0.01 sec)
            
  3. Anlegen einer ActiveRecord-Klasse ‘Mytable’ für meine Legacy-Tabelle
    In app/models/ anlegen von mytable.rb:
             1     class Mytable < ActiveRecord::Base
             2  
             3       @@counter = 1000
             4  
             5       set_table_name 'mytable'
             6       set_primary_key 'objectidentifier'
             7  
             8       before_save :create_oid
             9  
            10       def create_oid
            11         if self.id == nil then
            12           @@counter += 1
            13           self.id  = @@counter 
            14         end 
            15       end
            16     end
            

    Hier ist zu sehen, dass ich erstens den Default-Tabellennamen (mit set_table_name) angepasst habe, da die Legacy-Tabelle nicht der Plural-Namenskonvention für Tabellennamen genügt. Weiter wurde die Primärschlüsselspalte benannt (mit set_primary_key). Zu guter Letzt habe ich die Methode create_oid implementiert, die eigenständig den Primärschlüssel für eine Instanz vergibt, falls dieser noch nicht gesetzt ist. (ACHTUNG: create_oid ist nicht für den Einsatz in einer (Web-)Anwendung geeignet, sondern hier nur für den Demozweck implementiert.) Mit before_save wird sichergestellt, dass create_oid vor jedem Speichern aufgerufen wird.
  4. In der Rails-Konsole
    >> leitet Anweisungen ein, die ich geschrieben habe. Das andere sind die Antworten des Ruby-Interpreters.
                pg-269:~/rp ghadir$ script/console
    
                >> mt = Mytable.new :name => ‘TEST’
    
                >> Mytable.find :all
                #=> []
                >> mt.save
                => true
                >> Mytable.find :all
                => [#“TEST”, “objectidentifier”=>”1001”}>]
                >> mt = Mytable.new  :name => ‘TEST’                            
                => #“TEST”}>
                >> mt.save
                => true
                >> Mytable.find :all
                => [#“TEST”, “objectidentifier”=>”1001”}>, #“TEST”, “objectidentifier”=>”1002”}>]
    
            

Dieser Code ist natürlich unpraktisch, da ich nicht berücksichtige, dass objectidentifier eigentlich wieder der id zugewiesen werden muss, falls er gesetzt ist aber die id nicht. Sonst würde es mit den Scaffolds nicht funktionieren. Also ein gewisser Transfer muss gemacht werden. :-)

Ich hoffe trotzdem, dass klar geworden ist, dass auch die Anbindung einer Legacy-Tabelle mit wenigen Schritten getan werden kann.

Posted by Phillip Ghadir at June 1, 2007 7:23 PM