Могу ли я писать функции PostgreSQL в Ruby on Rails?

Мы начинаем проект на основе Ruby on Rails. Мы работали с функциями Perl и PostgreSQL, а с Rails и Active Record я не видел, как мы должны создавать функции в PostgreSQL и вести запись с помощью Active Record и моделей.

Я знаю, что мы можем создать его вручную в PostgreSQL, но "волшебство" с Active Record заключается в том, что базу данных можно воссоздать со всеми моделями.

Есть ли способ создать функцию PostgreSQL с помощью Rails и сохранить ее в моделях?

Ответ 1

Эта часть вашего вопроса:

Я знаю, что мы можем создать его вручную в PostgreSQL, но "волшебство" с Active Record заключается в том, что база данных может быть воссоздана со всеми моделями.

говорит мне, что вы действительно ищете способ интеграции функций PostgreSQL с обычным процессом миграции на Rails и задачами Rake, такими как db:schema:load.

Добавить и удалить функции в миграции легко:

def up
  connection.execute(%q(
    create or replace function ...
  ))
end

def down
  connection.execute(%q(
    drop function ...
  ))
end

Вам нужно использовать отдельные методы " up и " down вместо одного метода change потому что ActiveRecord не будет иметь представления о том, как применять, не говоря уже о том, чтобы отменить создание функции. И вы используете connection.execute для передачи необработанного определения функции в PostgreSQL. Вы также можете сделать это с помощью reversible внутреннего 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

но я считаю, что шумнее, чем up и down.

Однако schema.rb и обычные задачи Rake, которые работают с schema.rb (например, db:schema:load и db:schema:dump), не будут знать, что делать с функциями PostgreSQL и другими вещами, которые ActiveRecord не понимает., Существует способ обойти это, хотя, вы можете использовать structure.sql файл вместо schema.rb путем установки:

config.active_record.schema_format = :sql

в вашем файле config/application.rb. После этого db:migrate запишет файл db/structure.sql (который является просто необработанным db/schema.rb SQL вашей базы данных PostgreSQL без ваших данных) вместо db/schema.rb. Вы также будете использовать различные задачи Rake для работы со structure.sql:

  • db:structure:dump вместо db:schema:dump
  • db:structure:load вместо db:schema:load

Все остальное должно работать так же.

Этот подход также позволяет вам использовать в вашей базе данных другие вещи, которые ActiveRecord не поймет: ограничения CHECK, триггеры, непросто настроенные значения по умолчанию для столбцов,...

Ответ 2

Если ваше единственное требование создает их где-то в вашем приложении Rails, это возможно через ActiveRecord::Base.connection.execute, который вы можете использовать для выполнения необработанных SQL-запросов.

stmt = 'CREATE FUNCTION...'
ActiveRecord::Base.connection.execute stmt

Затем вы вызовете функцию с помощью ActiveRecord::Base.connection.execute (я бы предположил, что у вас есть методы в вашей модели, чтобы справиться с этим).