5

Ich arbeite an einem Projekt, wo ich der Datenbank Designer/Admin in einer PostgreSQL-Umgebung bin. Der Leiter hat sich entschieden, Rails für die Anwendungslogik zu verwenden und rekrutierte einen Rails-Programmierer.Aufruf von PL/pgSQL Stored Procedures von Ruby on Rails

Der Rails-Programmierer sagte, dass er normalerweise den gesamten Anwendungscode programmiert und den Mangel an Kontrolle nicht mag, wenn ihm jemand eine gespeicherte Prozedur übergibt, und dass er es noch nie in Rails getan hat.

Die Datenbank verwendet eine große Menge an Vererbung/EERM, so dass gespeicherte Prozeduren und Trigger die Arbeit erheblich erleichtern, zusätzlich zu den Leistungsvorteilen bei der Verwendung von Procs.

Ich habe vier Fragen:

1) Wie ohne Rückgabewert

2) Wie eine pl/pgSQL gespeicherte Prozedur von Rails rufen Sie einen pl/pgSQL gespeicherte Prozedur von Rails mit einem einzigen nennen Rückgabewert (1 Zeile/1 Spalte)

3) So rufen Sie eine gespeicherte pl/pgSQL-Prozedur von Rails mit einem 1-Zeilen-Rückgabewert für viele Spalten auf.

4) So rufen Sie eine gespeicherte pl/pgSQL-Prozedur von Rails mit einem OUT-Parameter auf?

Danke!

+6

Du wirst eine schlechte Zeit haben, kann Ihren Rails-Programmierer dazu bringen, etwas wie [Sequel] (http://sequel.rubyforge.org) zu verwenden. Das Standard Rails ORM (ActiveRecord) glaubt nicht, dass die Datenbank irgendeine Logik enthalten sollte und nichts komplizierter als 'select *' und einfache Joins versteht. Sie werden es immer bekämpfen, wenn Sie gegen die Konventionen verstoßen Verwenden Sie "ausgefallene" Dinge wie Trigger, gespeicherte Prozeduren oder sogar vorbereitete Anweisungen. –

+2

Ja ... Proc und Vererbung basierend DB + ActiveRecord führt Sie direkt in http://thedailywtf.com/ Territory. Sie müssen mit der Entscheidung leben, für Rails (und vermutlich seine ActiveRecord ORM) zu gehen und Ihr DB-Design aus dem Fenster zu werfen, dann ein, das den ActiveRecord-Konvalenzen folgt (keine albernen Dinge wie "Fremdschlüssel" oder "Einschränkungen"), wer würde sie überhaupt wollen?). Alternativ kannst du die Entscheidung ändern und sehen, ob du, wie Mu merkt, wenigstens ein vernünftiges ORM benutzen kannst. –

Antwort

7

Hallo ich diesen Code bin mit mit PgSQL gespeicherten Prozeduren arbeiten Diese

class SpActiveRecord < ActiveRecord::Base 

     self.abstract_class = true 
     #without return value 
     def self.execute_sp(sql, *bindings) 
     perform_sp(:execute, sql, *bindings) 
     end 
     #select many return values 
     def self.fetch_sp(sql, *bindings) 
     perform_sp(:select_all, sql, *bindings) 
     end 
     #select single return value 
     def self.fetch_sp_val(sql, *bindings) 
     perform_sp(:select_value, sql, *bindings) 
     end 

     protected 
     def self.perform_sp(method, sql, *bindings) 
     if bindings.any? 
      sql = self.send(:sanitize_sql_array, bindings.unshift(sql)) 
     end 
     self.connection.send(method, sql) 
     end 

    end 

Beispiel, wenn Sie alle außer Ihrer letzten Frage deckt

class Invoice < SpActiveRecord 

def create_or_update 
     raise ReadOnlyRecord if readonly? or !new_record? 

     self.id = fetch_sp_val("SELECT * FROM billing.invoice_generate(?,?,?)", 
           self.account_id, 
           self.start_date, 
           self.end_date) 

     @new_record = false 
     true 
    end 
end