Phần câu hỏi này của bạn:
Tôi biết chúng ta có thể tạo nó theo cách thủ công trong PostgreSQL, nhưng "điều kỳ diệu" với Active Record là cơ sở dữ liệu có thể được tạo lại với tất cả các mô hình.
cho tôi biết rằng bạn thực sự đang tìm cách tích hợp các chức năng PostgreSQL với quy trình di chuyển Rails thông thường và các tác vụ Rake chẳng hạn như db:schema:load
.
Thêm và xóa các chức năng trong di chuyển thật dễ dàng:
def up
connection.execute(%q(
create or replace function ...
))
end
def down
connection.execute(%q(
drop function ...
))
end
Bạn cần sử dụng up
riêng biệt và down
thay vì một change
bởi vì ActiveRecord sẽ không biết cách áp dụng chứ đừng nói đến việc đảo ngược việc tạo hàm. Và bạn sử dụng connection.execute
để cung cấp định nghĩa hàm thô cho PostgreSQL. Bạn cũng có thể thực hiện việc này với reversible
bên trong change
:
def change
reversible do |dir|
dir.up do
connection.execute(%q(
create or replace function ...
))
end
dir.down do
connection.execute(%q(
drop function ...
))
end
end
end
nhưng tôi thấy nó ồn hơn up
và down
.
Tuy nhiên, schema.rb
và các tác vụ Rake thông thường hoạt động với schema.rb
(chẳng hạn như db:schema:load
và db:schema:dump
) sẽ không biết phải làm gì với các hàm PostgreSQL và những thứ khác mà ActiveRecord không hiểu. Tuy nhiên, có một cách để giải quyết vấn đề này, bạn có thể chọn sử dụng structure.sql
thay vì schema.rb
bằng cách cài đặt:
config.active_record.schema_format = :sql
trong config/application.rb
của bạn tập tin. Sau đó, db:migrate
sẽ viết một db/structure.sql
tệp (chỉ là một kết xuất SQL thô của cơ sở dữ liệu PostgreSQL mà không có dữ liệu của bạn) thay vì db/schema.rb
. Bạn cũng sẽ sử dụng các tác vụ Rake khác nhau để làm việc với structure.sql
:
-
db:structure:dump
thay vìdb:schema:dump
-
db:structure:load
thay vìdb:schema:load
Mọi thứ khác sẽ hoạt động như cũ.
Cách tiếp cận này cũng cho phép bạn sử dụng những thứ khác trong cơ sở dữ liệu của mình mà ActiveRecord sẽ không hiểu:KIỂM TRA các ràng buộc, trình kích hoạt, mặc định cột không đơn giản, ...