5

Tôi đang làm việc trên một dự án mà tôi là nhà thiết kế cơ sở dữ liệu/quản trị viên trong môi trường PostgreSQL. Các nhà lãnh đạo đã quyết định sử dụng Rails cho logic ứng dụng và tuyển dụng một lập trình Rails.Gọi thủ tục lưu trữ PL/pgSQL từ Ruby on Rails

Lập trình viên Rails nói rằng anh thường lập trình tất cả mã ứng dụng và không thích việc kiểm soát được trình bày bởi có ai đó vượt qua anh ta một thủ tục lưu trữ và anh chưa bao giờ làm điều đó trong đường ray.

Cơ sở dữ liệu sử dụng rất nhiều kế thừa/EERM, vì vậy các thủ tục và trình kích hoạt được lưu trữ sẽ giúp công việc của mình dễ dàng hơn nhiều, ngoài lợi ích hiệu suất từ ​​việc sử dụng procs.

Tôi có bốn câu hỏi:

1) Làm thế nào để gọi một pl/pgSQL thủ tục lưu trữ từ Rails không có giá trị trả về

2) Làm thế nào để gọi một pl/pgSQL thủ tục lưu trữ từ Rails với một đơn giá trị trả lại (1 hàng/1 cột)

3) Cách gọi thủ tục lưu trữ pl/pgSQL từ Rails với giá trị trả về nhiều cột 1 hàng.

4) Cách gọi thủ tục lưu trữ pl/pgSQL từ Rails bằng tham số OUT?

Cảm ơn!

+6

Bạn sẽ có một thời gian xấu, trừ khi bạn có thể thuyết phục người lập trình Rails của bạn sử dụng một cái gì đó như [Sequel] (http://sequel.rubyforge.org). Mặc định Rails ORM (ActiveRecord) không tin rằng cơ sở dữ liệu nên chứa bất kỳ logic nào và không hiểu bất cứ điều gì phức tạp hơn 'select *' và join đơn giản, bạn sẽ luôn chiến đấu nếu bạn vi phạm các quy ước sử dụng những thứ "lạ mắt" như trình kích hoạt, thủ tục lưu sẵn hoặc thậm chí là các câu lệnh chuẩn bị sẵn sàng. –

+2

Vâng ... proc và thừa kế dựa trên DB + ActiveRecord sẽ dẫn bạn thẳng vào lãnh thổ http://thedailywtf.com/. Bạn phải sống với quyết định đi tới Rails (và có lẽ là ActiveRecord ORM) và ném thiết kế DB của bạn ra ngoài cửa sổ, sau đó tạo một cái theo sau các kết nối ActiveRecord (không có những thứ ngớ ngẩn như "khóa ngoài" hoặc "ràng buộc", ai cũng muốn họ?). Cách khác, thay đổi quyết định và xem nếu như Mu ghi chú bạn có thể nhận được chúng ít nhất là sử dụng một ORM sane-ish. –

Trả lời

7

Xin chào Tôi đang sử dụng mã này để làm việc với các thủ tục lưu trữ pgSQL này bao gồm tất cả ngoại trừ câu hỏi cuối cùng của bạn

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 

Ví dụ

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 
Các vấn đề liên quan